From 12a1329101949cbdece4df096cb565e2ac4f614a Mon Sep 17 00:00:00 2001 From: CPunch Date: Thu, 3 Mar 2022 10:57:33 -0600 Subject: [PATCH] Removed Panel client, updated README requirements --- README.md | 4 +- panel/CMakeLists.txt | 22 -- panel/include/panel.h | 104 --------- panel/include/pbot.h | 25 --- panel/include/pclient.h | 24 -- panel/src/main.c | 100 --------- panel/src/panel.c | 486 ---------------------------------------- panel/src/pbot.c | 56 ----- panel/src/pclient.c | 202 ----------------- 9 files changed, 2 insertions(+), 1021 deletions(-) delete mode 100644 panel/CMakeLists.txt delete mode 100644 panel/include/panel.h delete mode 100644 panel/include/pbot.h delete mode 100644 panel/include/pclient.h delete mode 100644 panel/src/main.c delete mode 100644 panel/src/panel.c delete mode 100644 panel/src/pbot.c delete mode 100644 panel/src/pclient.c diff --git a/README.md b/README.md index 18f4fd0..4102ff5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Laika -Laika is a simple Remote Access Toolkit stack for red teaming. It allows authenticated communication across a custom protocol with generated key pairs which are embedded into the executable (only the public key is embedded in the bot client ofc). +Laika is a simple Remote Access Toolkit stack for red teaming. It allows authenticated communication across a custom protocol with generated key pairs which are embedded into the executable (only the public key is embedded in the bot client ofc). This project currently only targets Linux, however the socket API has already been ported to work under various OS including Windows, Linux & MacOS. Cross-platform support for the bot client will come eventually. Some notable features thus far: - [X] Lightweight, the bot alone is 270kb (22kb if not statically linked with LibSodium) and uses very little resources. @@ -22,13 +22,13 @@ I could add some padding to each packet to make it look pseudo-HTTP-like, howeve - `/cnc` is the Command aNd Control server. - `/bot` is the bot client to be ran on the target machine. - `/shell` is the main shell to connect to the CNC server with to issue commands. -- `/panel` is a very incomplete & broken ncurses client. ignore for now. - `/tools` holds tools for generating keypairs, etc. ## Configuration and compilation Make sure you have the following libraries and tools installed: - CMake (>=3.10) +- Compiler with C11 support (GCC >= 4.7, Clang >= 3.1, etc.) - LibSodium (static library) First, compile the target normally diff --git a/panel/CMakeLists.txt b/panel/CMakeLists.txt deleted file mode 100644 index 6639ba3..0000000 --- a/panel/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -set(PANEL_INCLUDEDIR ${CMAKE_CURRENT_SOURCE_DIR}/include) -set(CURSES_NEED_NCURSES TRUE) - -project(LaikaPanel VERSION 1.0) - -# Put CMake targets (ALL_BUILD/ZERO_CHECK) into a folder -set_property(GLOBAL PROPERTY USE_FOLDERS ON) - -find_package(Curses) - -# compile LaikaPanel -file(GLOB_RECURSE PANELSOURCE ${CMAKE_CURRENT_SOURCE_DIR}/src/**.c) -add_executable(LaikaPanel ${PANELSOURCE}) -target_link_libraries(LaikaPanel PUBLIC LaikaLib ${CURSES_LIBRARIES}) - -# add the 'DEBUG' preprocessor definition if we're compiling as Debug -target_compile_definitions(LaikaPanel PUBLIC "$<$:DEBUG>") - -# add include directory -target_include_directories(LaikaPanel PUBLIC ${PANEL_INCLUDEDIR}) diff --git a/panel/include/panel.h b/panel/include/panel.h deleted file mode 100644 index 4bf4a4e..0000000 --- a/panel/include/panel.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef PANELMENU_H -#define PANELMENU_H - -#include -#include - -#define PANEL_CURSES_TIMEOUT 100 -#define COMMONPANELLIST tPanel_list list; - -typedef void (*panelCallback)(void *uData); - -typedef enum { - LIST_LIST, - LIST_TABS, - LIST_MENU, - LIST_TEXT, - LIST_NONE -} LISTTYPE; - -struct sPanel_list; -typedef struct sPanel_listItem { - panelCallback callback; - struct sPanel_list *child; - void *uData; - char *name; - struct sPanel_listItem *next; - struct sPanel_listItem *last; - int x, y, width, height; -} tPanel_listItem; - -typedef struct sPanel_list { - tPanel_listItem *itemHead, *selectedItem; - WINDOW *win; - int x, y, width, height; - LISTTYPE type; - bool hidden; -} tPanel_list; - -typedef struct sPanel_tabs { - COMMONPANELLIST; - char *title; -} tPanel_tabs; - -typedef struct sPanel_menu { - COMMONPANELLIST; - char *title; -} tPanel_menu; - -typedef struct sPanel_text { - COMMONPANELLIST; - char *title; - char *text; -} tPanel_text; - -extern WINDOW *wmain; -extern tPanel_list *panel_botList; -extern tPanel_tabs *panel_tabList; - -void panel_init(void); -void panel_cleanUp(void); - -tPanel_list *panel_getActiveList(void); -int panel_getChar(void); -void panel_pushActiveList(tPanel_list *list); -void panel_popActiveList(void); /* also free's the item */ -void panel_draw(void); -bool panel_tick(int input); /* ticks activeList list, returns true if input was accepted/valid */ -void panel_setTimeout(int timeout); - -tPanel_listItem *panelL_newListItem(tPanel_list *list, tPanel_list *child, char *name, panelCallback callback, void *uData); -void panelL_freeListItem(tPanel_list *list, tPanel_listItem *item); - -/* call *after* adding listItems with panelL_newListItem */ -void panelL_init(tPanel_list *list); -void panelL_draw(tPanel_list *list); -void panelL_free(tPanel_list *list); -bool panelL_tick(tPanel_list *list, int ch); -void panelL_setHidden(tPanel_list *list, bool hidden); -void panelL_setTimeout(tPanel_list *list, int timeout); - -/* handles selection */ -void panelL_nextItem(tPanel_list *list); -void panelL_prevItem(tPanel_list *list); -void panelL_selectItem(tPanel_list *list); /* calls select item's callback */ - -/* center list */ -tPanel_list *panelL_newList(void); -void panelL_freeList(tPanel_list *list); - -/* top tabs */ -tPanel_tabs *panelL_newTabs(char *title); -void panelL_freeTabs(tPanel_tabs *tabs); - -/* menu popup */ -tPanel_menu *panelL_newMenu(char *title); -void panelL_freeMenu(tPanel_menu *menu); - -/* textbot popup */ -tPanel_text *panelL_newText(char *title, char *text); -void panelL_freeText(tPanel_text *text); - -#undef COMMONPANELLIST - -#endif \ No newline at end of file diff --git a/panel/include/pbot.h b/panel/include/pbot.h deleted file mode 100644 index 43f74a3..0000000 --- a/panel/include/pbot.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef PBOT_H -#define PBOT_H - -#include "laika.h" -#include "lpeer.h" -#include "lsodium.h" - -#include "panel.h" - -typedef struct sPanel_bot { - uint8_t pub[crypto_kx_PUBLICKEYBYTES]; - char hostname[LAIKA_HOSTNAME_LEN], ipv4[LAIKA_IPV4_LEN]; - PEERTYPE type; - tPanel_listItem *item; - char *name; /* heap allocated string */ -} tPanel_bot; - -tPanel_bot *panelB_newBot(uint8_t *pubKey, char *hostname, char *ipv4); -void panelB_freeBot(tPanel_bot *bot); - -/* search connected bots by public key */ -tPanel_bot *panelB_getBot(uint8_t *pubKey); -void panelB_setItem(tPanel_bot *bot, tPanel_listItem *item); - -#endif \ No newline at end of file diff --git a/panel/include/pclient.h b/panel/include/pclient.h deleted file mode 100644 index 770a96e..0000000 --- a/panel/include/pclient.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef PCLIENT_H -#define PCLIENT_H - -#include "laika.h" -#include "lpeer.h" -#include "lpolllist.h" -#include "pbot.h" - -typedef struct sPanel_client { - uint8_t priv[crypto_kx_SECRETKEYBYTES], pub[crypto_kx_PUBLICKEYBYTES]; - struct sLaika_pollList pList; - struct sLaika_peer *peer; -} tPanel_client; - -tPanel_client *panelC_newClient(); -void panelC_freeClient(tPanel_client *client); - -void panelC_connectToCNC(tPanel_client *client, char *ip, char *port); /* can throw a LAIKA_ERROR */ -bool panelC_poll(tPanel_client *client, int timeout); - -void panelC_addBot(tPanel_bot *bot); -void panelC_rmvBot(tPanel_bot *bot); - -#endif diff --git a/panel/src/main.c b/panel/src/main.c deleted file mode 100644 index 3a6a095..0000000 --- a/panel/src/main.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "laika.h" -#include "lerror.h" - -#include "panel.h" -#include "pclient.h" - -#define STRING(x) #x -#define MACROLITSTR(x) STRING(x) - -tPanel_client *client; -tPanel_tabs *panel_tabList; -tPanel_list *panel_botList; - -void connectToCNC(void *uData) { - tPanel_listItem *curr; - int ch; - - /* hide main menu */ - panelL_setHidden(panel_getActiveList(), true); - - /* init global lists */ - panel_tabList = panelL_newTabs("Laika CNC Panel"); - panel_botList = panelL_newList(); - - /* init tabs */ - panelL_newListItem(&panel_tabList->list, NULL, "CNC Flags", NULL, NULL); - panelL_newListItem(&panel_tabList->list, panel_botList, "Bot List", NULL, NULL); - panelL_init(&panel_tabList->list); - panelL_init(panel_botList); - - addstr("Connecting to CNC with pubkey [" LAIKA_PUBKEY "]..."); - refresh(); - - client = panelC_newClient(); - panelC_connectToCNC(client, "127.0.0.1", "13337"); - - /* main panel loop */ - panel_pushActiveList(&panel_tabList->list); - while ((ch = panel_getChar()) != 'q' && laikaS_isAlive((&client->peer->sock))) { - if (!panel_tick(ch)) { - /* if we got an event to handle, we *probably* have more events to handle so temporarily make ncurses non-blocking */ - if (panelC_poll(client, 0)) { - panel_setTimeout(0); /* makes ncurses non-blocking */ - panel_draw(); - } else { - /* wait to poll if we didn't receive any new messages */ - panel_setTimeout(PANEL_CURSES_TIMEOUT); - } - } else { - /* we got input, redraw screen */ - panel_draw(); - } - } - - /* free bots in botList */ - curr = panel_botList->itemHead; - while (curr != NULL) { - panelB_freeBot(curr->uData); - curr = curr->next; - } - - /* since panel_botList is a child of one of panel_tabList's items, it - gets free'd with panel_tabList. so popping it frees both */ - panel_popActiveList(); - panelC_freeClient(client); - - /* re-show main menu */ - panelL_setHidden(panel_getActiveList(), false); -} - -void quitLaika(void *uData) { - LAIKA_ERROR("quit!\n"); -} - -int main(int argv, char **argc) { - tPanel_menu *menu; - int ch; - - /* init ncurses */ - panel_init(); - - menu = panelL_newMenu("Laika v" MACROLITSTR(LAIKA_VERSION_MAJOR) "." MACROLITSTR(LAIKA_VERSION_MINOR)); - panelL_newListItem(&menu->list, NULL, "Quit", quitLaika, NULL); - panelL_newListItem(&menu->list, NULL, "- Connect to CNC", connectToCNC, NULL); - - /* start main menu */ - panelL_init(&menu->list); - panel_pushActiveList(&menu->list); - LAIKA_TRY - while ((ch = panel_getChar()) != 'q') { - if (panel_tick(ch)) - panel_draw(); - } - LAIKA_TRYEND - panel_popActiveList(); - - /* cleanup */ - panel_cleanUp(); - return 0; -} \ No newline at end of file diff --git a/panel/src/panel.c b/panel/src/panel.c deleted file mode 100644 index 3e461de..0000000 --- a/panel/src/panel.c +++ /dev/null @@ -1,486 +0,0 @@ -#include -#include -#include "lmem.h" -#include "lerror.h" -#include "panel.h" -#include "pbot.h" - -/* i don't expect to ever be 16 layers deep of menus */ -#define ACTIVESIZE 16 - -WINDOW *wmain; - -tPanel_list *activeList[ACTIVESIZE] = { NULL }; -int activeListSize = -1; - -void printTitle(WINDOW *win, char *text, int width, int x, int y) { - int pad = (width - (strlen(text) + 4)) / 2; - mvwprintw(win, y, x+pad, "| %s |", text); -} - -void printCenter(WINDOW *win, char *text, int width, int x, int y) { - int strLength = strlen(text); - int pad = (width - strLength) / 2; - mvwprintw(win, y, x, "%*s%s%*s", pad, "", text, (width-pad-strLength), ""); -} - -void printLine(WINDOW *win, char *text, int width, int x, int y) { - int strLength = strlen(text); - int pad = (width - strLength); - mvwprintw(win, y, x, "%s%*s\n", text, pad, ""); -} - -void panel_init() { - if ((wmain = initscr()) == NULL) - LAIKA_ERROR("Failed to init ncurses!"); - - activeListSize = -1; - - /* setup ncurses */ - cbreak(); - noecho(); - timeout(1); - keypad(stdscr, true); - curs_set(0); /* hide the default screen cursor. */ - - refresh(); -} - -void panel_cleanUp() { - /* clean up ncurses */ - delwin(wmain); - endwin(); -} - -tPanel_list *panel_newBaseList(size_t sz, LISTTYPE type) { - tPanel_list *list = laikaM_malloc(sz); - - list->itemHead = NULL; - list->selectedItem = NULL; - list->win = NULL; - list->x = 1; - list->y = 0; - list->height = 0; - list->type = type; - list->hidden = false; - - return list; -} - -void panel_freeBaseList(tPanel_list *list) { - /* free linked list */ - tPanel_listItem *curr = list->itemHead, *last = NULL; - - while(curr != NULL) { - last = curr; - curr = curr->next; - if (last != NULL) - panelL_freeListItem(list, last); - } - - /* remove ncurses window */ - wclear(list->win); - delwin(list->win); - - /* free list */ - laikaM_free(list); -} - -tPanel_list *panel_getActiveList() { - return activeList[activeListSize]; -} - -int panel_getChar() { - /* if we have an activeList panel, grab the input from that otherwise return -1 */ - if (panel_getActiveList() != NULL) - return wgetch(panel_getActiveList()->win); - return -1; -} - -void panel_pushActiveList(tPanel_list *list) { - /* set activeList window & draw */ - activeList[++activeListSize] = list; - panelL_draw(panel_getActiveList()); -} - -void panel_popActiveList() { - panelL_freeList(activeList[activeListSize--]); - - if (activeListSize >= 0) - panelL_init(panel_getActiveList()); -} - -void panel_draw(void) { - int i; - - /* draw active panels from bottom most (pushed first) to top most (pushed last) - this way, new-er windows will be drawn on-top of older ones */ - clear(); - for (i = 0; i <= activeListSize; i++) { - panelL_draw(activeList[i]); - } -} - -bool panel_tick(int ch) { - int i; - /* tick each panel from top most (pushed last) to bottom most (pushed first) - this way, the top-most windows/lists will be the most interactive */ - - for (i = activeListSize; i >= 0; i--) { - if (panelL_tick(activeList[i], ch)) - return true; - } - - /* no ticks returned any results */ - return false; -} - -void panel_setTimeout(int timeout) { - panelL_setTimeout(panel_getActiveList(), timeout); -} - -/* ==================================================[[ List ]]================================================== */ - -tPanel_list *panelL_newList(void) { - return (tPanel_list*)panel_newBaseList(sizeof(tPanel_list), LIST_LIST); -} - -void panelL_freeList(tPanel_list *list) { - panel_freeBaseList(list); -} - -void panelL_initList(tPanel_list *list) { - tPanel_listItem *curr = list->itemHead; - int numLines = 0; - - /* count # of lines */ - while (curr != NULL) { - numLines++; - curr = curr->next; - } - - /* create ncurses window */ - list->x = 0; - list->y = 2; - list->width = COLS; - list->height = numLines; - list->win = newwin(list->height, list->width, list->y, list->x); - keypad(list->win, TRUE); /* setup keyboard input */ - wtimeout(list->win, 0); -} - -void panelL_drawList(tPanel_list *list) { - tPanel_listItem *curr = list->itemHead; - int i = 0; - - /* write each line */ - while (curr != NULL) { - /* highlight selected option */ - if (curr == list->selectedItem) - wattron(list->win, A_STANDOUT); - - printLine(list->win, curr->name, list->width, 0, i++); - wattroff(list->win, A_STANDOUT); - curr = curr->next; - } - - /* push to screen */ - wrefresh(list->win); -} - -bool panelL_tickList(tPanel_list *list, int ch) { - switch (ch) { - case KEY_DOWN: panelL_nextItem(list); break; - case KEY_UP: panelL_prevItem(list); break; - default: return false; - } - - return true; -} - -/* ==================================================[[ Tabs ]]================================================== */ - -tPanel_tabs *panelL_newTabs(char *title) { - tPanel_tabs *tabs = (tPanel_tabs*)panel_newBaseList(sizeof(tPanel_tabs), LIST_TABS); - tabs->title = title; - tabs->list.width = strlen(title) + 4; - - return tabs; -} - -void panelL_freeTabs(tPanel_tabs *tabs) { - panel_freeBaseList((tPanel_list*)tabs); -} - -void panelL_initTabs(tPanel_list *tabs) { - tPanel_listItem *curr = tabs->itemHead; - int numTabs = 0; - - if (tabs->win) - delwin(tabs->win); - - /* get tab count */ - while (curr != NULL) { - curr = curr->next; - numTabs++; - } - - tabs->x = 0; - tabs->y = 0; - if (numTabs <= 1) - tabs->width = COLS; - else - tabs->width = COLS/numTabs; - tabs->height = 2; - tabs->win = newwin(tabs->height, COLS, tabs->y, tabs->x); - - keypad(tabs->win, true); - wtimeout(tabs->win, 0); -} - -void panelL_drawTabs(tPanel_tabs *tabs) { - tPanel_listItem *curr = tabs->list.itemHead; - int i = 0; - - /* write title */ - printCenter(tabs->list.win, tabs->title, COLS, 0, 0); - - /* write each tab */ - while (curr != NULL) { - /* highlight selected option */ - if (curr == tabs->list.selectedItem) - wattron(tabs->list.win, A_STANDOUT); - - printCenter(tabs->list.win, curr->name, tabs->list.width, (i++)*tabs->list.width, 1); - curr = curr->next; - wattroff(tabs->list.win, A_STANDOUT); - } - - /* draw tab */ - refresh(); - if (tabs->list.selectedItem && tabs->list.selectedItem->child) - panelL_draw(tabs->list.selectedItem->child); - - wrefresh(tabs->list.win); -} - -bool panelL_tickTabs(tPanel_tabs *tabs, int ch) { - switch (ch) { - case KEY_RIGHT: panelL_nextItem(&tabs->list); break; - case KEY_LEFT: panelL_prevItem(&tabs->list); break; - /* tick child */ - default: return (tabs->list.selectedItem && tabs->list.selectedItem->child) ? panelL_tick(tabs->list.selectedItem->child, ch) : false; - } - - return true; -} - -/* ==================================================[[ Menu ]]================================================== */ - -tPanel_menu *panelL_newMenu(char *title) { - tPanel_menu *menu = (tPanel_menu*)panel_newBaseList(sizeof(tPanel_menu), LIST_MENU); - menu->title = title; - menu->list.width = strlen(title) + 4; - - return menu; -} - -void panelL_freeMenu(tPanel_menu *menu) { - panel_freeBaseList((tPanel_list*)menu); -} - -void panelL_initMenu(tPanel_list *menu) { - tPanel_listItem *curr = menu->itemHead; - - if (menu->win) - delwin(menu->win); - - /* get max line length & menu height */ - menu->height = 2; - while (curr != NULL) { - if (curr->width+6 > menu->width) - menu->width = curr->width+6; - - curr = curr->next; - menu->height++; - } - - menu->y = (LINES-menu->height)/2; - menu->x = (COLS-menu->width)/2; - - menu->win = newwin(menu->height, menu->width, menu->y, menu->x); - keypad(menu->win, true); - wtimeout(menu->win, 0); -} - -void panelL_drawMenu(tPanel_menu *menu) { - tPanel_listItem *curr = menu->list.itemHead; - int i = 1; - - /* write each line */ - while (curr != NULL) { - /* highlight selected option */ - if (curr == menu->list.selectedItem) - wattron(menu->list.win, A_STANDOUT); - - printLine(menu->list.win, curr->name, menu->list.width-4, 2, i++); - wattroff(menu->list.win, A_STANDOUT); - curr = curr->next; - } - - /* write the title & border */ - box(menu->list.win, 0, 0); - printTitle(menu->list.win, menu->title, menu->list.width, 0, 0); - - /* push to screen */ - wrefresh(menu->list.win); -} - -bool panelL_tickMenu(tPanel_menu *menu, int ch) { - switch (ch) { - case KEY_UP: panelL_prevItem(&menu->list); break; - case KEY_DOWN: panelL_nextItem(&menu->list); break; - case '\n': case KEY_ENTER: panelL_selectItem(&menu->list); break; - default: return false; - } - - panelL_drawMenu(menu); - return true; -} - -/* ==================================================[[ Text ]]================================================== */ - -tPanel_text *panelL_newText(char *title, char *text) { - tPanel_text *textP = (tPanel_text*)panel_newBaseList(sizeof(tPanel_text), LIST_TEXT); - textP->title = title; - textP->list.width = strlen(title) + 4; - - return textP; -} - -void panelL_freeText(tPanel_text *textP) { - panel_freeBaseList((tPanel_list*)textP); -} - -/* ==============================================[[ Panel Direct ]]============================================== */ - -tPanel_listItem *panelL_newListItem(tPanel_list *list, tPanel_list *child, char *name, panelCallback callback, void *uData) { - tPanel_listItem *item = laikaM_malloc(sizeof(tPanel_listItem)); - - item->child = child; - item->callback = callback; - item->uData = uData; - item->name = name; - item->last = NULL; - item->next = NULL; - item->width = strlen(name); - item->height = 1; - item->x = 0; - item->y = 0; - - /* add to list */ - if (list->itemHead) - list->itemHead->last = item; - - item->next = list->itemHead; - list->itemHead = item; - list->selectedItem = item; - - return item; -} - -void panelL_freeListItem(tPanel_list *list, tPanel_listItem *item) { - if (list->itemHead == item) { - if (item->next) - item->next->last = NULL; - list->itemHead = item->next; - } else { - /* unlink from list */ - if (item->last) - item->last->next = item->next; - - if (item->next) - item->next->last = item->last; - } - - /* free child */ - if (item->child) - panelL_freeList(item->child); - - /* update selected item */ - if (list->selectedItem == item) - list->selectedItem = list->itemHead; - - laikaM_free(item); -} - -void panelL_nextItem(tPanel_list *list) { - if (!list->selectedItem || !list->selectedItem->next) /* sanity check */ - return; - - list->selectedItem = list->selectedItem->next; -} - -void panelL_prevItem(tPanel_list *list) { - if (!list->selectedItem || !list->selectedItem->last) /* sanity check */ - return; - - list->selectedItem = list->selectedItem->last; -} - -void panelL_selectItem(tPanel_list *list) { - if (!list->selectedItem || !list->selectedItem->callback) /* sanity check */ - return; - - list->selectedItem->callback(list->selectedItem->uData); -} - -void panelL_init(tPanel_list *list) { - switch (list->type) { - case LIST_LIST: panelL_initList(list); break; - case LIST_TABS: panelL_initTabs(list); break; - case LIST_MENU: panelL_initMenu(list); break; - default: LAIKA_ERROR("Malformed tPanel_list!\n"); break; - } -} - -void panelL_free(tPanel_list *list) { - switch (list->type) { - case LIST_LIST: panelL_freeList(list); break; - case LIST_TABS: panelL_freeTabs((tPanel_tabs*)list); break; - case LIST_MENU: panelL_freeMenu((tPanel_menu*)list); break; - default: LAIKA_ERROR("Malformed tPanel_list!\n"); break; - } -} - -void panelL_draw(tPanel_list *list) { - if (list->hidden) /* don't draw a hidden list */ - return; - - switch (list->type) { - case LIST_LIST: panelL_drawList(list); break; - case LIST_TABS: panelL_drawTabs((tPanel_tabs*)list); break; - case LIST_MENU: panelL_drawMenu((tPanel_menu*)list); break; - default: LAIKA_ERROR("Malformed tPanel_list!\n"); break; - } -} - -bool panelL_tick(tPanel_list *list, int ch) { - if (list->hidden) /* don't tick a hidden list */ - return false; - - switch (list->type) { - case LIST_LIST: return panelL_tickList(list, ch); - case LIST_TABS: return panelL_tickTabs((tPanel_tabs*)list, ch); - case LIST_MENU: return panelL_tickMenu((tPanel_menu*)list, ch); - default: return false; - } -} - -void panelL_setHidden(tPanel_list *list, bool hidden) { - list->hidden = hidden; -} - -void panelL_setTimeout(tPanel_list *list, int timeout) { - wtimeout(list->win, timeout); -} \ No newline at end of file diff --git a/panel/src/pbot.c b/panel/src/pbot.c deleted file mode 100644 index 9acd9aa..0000000 --- a/panel/src/pbot.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "lmem.h" -#include "lerror.h" -#include "pbot.h" - -#include "panel.h" - -tPanel_bot *panelB_newBot(uint8_t *pubKey, char *hostname, char *ipv4) { - tPanel_bot *bot = laikaM_malloc(sizeof(tPanel_bot)); - int length; - - /* copy pubKey to bot's pubKey */ - memcpy(bot->pub, pubKey, crypto_kx_PUBLICKEYBYTES); - - /* copy hostname & ipv4 */ - memcpy(bot->hostname, hostname, LAIKA_HOSTNAME_LEN); - memcpy(bot->ipv4, ipv4, LAIKA_IPV4_LEN); - - /* restore NULL terminators */ - bot->hostname[LAIKA_HOSTNAME_LEN-1] = 0; - bot->ipv4[LAIKA_IPV4_LEN-1] = 0; - - /* make bot name */ - length = strlen(bot->hostname) + 1 + strlen(bot->ipv4) + 1; - bot->name = laikaM_malloc(length); - sprintf(bot->name, "%s@%s", bot->hostname, bot->ipv4); - - return bot; -} - -void panelB_freeBot(tPanel_bot *bot) { - laikaM_free(bot->name); - laikaM_free(bot); -} - -/* search connected bots by public key */ -tPanel_bot *panelB_getBot(uint8_t *pubKey) { - tPanel_listItem *curr = panel_botList->itemHead; - tPanel_bot *bot; - - while (curr != NULL) { - bot = (tPanel_bot*)curr->uData; - - /* check pubKeys */ - if (memcmp(pubKey, bot->pub, crypto_kx_PUBLICKEYBYTES) == 0) - return bot; /* they match! */ - - curr = curr->next; - } - - /* no match found :( */ - return NULL; -} - -void panelB_setItem(tPanel_bot *bot, tPanel_listItem *item) { - bot->item = item; -} \ No newline at end of file diff --git a/panel/src/pclient.c b/panel/src/pclient.c deleted file mode 100644 index 3ccdf76..0000000 --- a/panel/src/pclient.c +++ /dev/null @@ -1,202 +0,0 @@ -#include "lmem.h" -#include "lerror.h" -#include "pclient.h" -#include "panel.h" - -void handleHandshakeResponse(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { - tPanel_client *client = (tPanel_client*)uData; - uint8_t endianness = laikaS_readByte(&peer->sock); - - peer->sock.flipEndian = endianness != laikaS_isBigEndian(); -} - -void handleAddPeer(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { - char hostname[LAIKA_HOSTNAME_LEN], ipv4[LAIKA_IPV4_LEN]; - uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; - uint8_t type; - - /* read newly connected peer's pubKey */ - laikaS_read(&peer->sock, pubKey, crypto_kx_PUBLICKEYBYTES); - - /* read hostname & ipv4 */ - laikaS_read(&peer->sock, hostname, LAIKA_HOSTNAME_LEN); - laikaS_read(&peer->sock, ipv4, LAIKA_IPV4_LEN); - - /* read peer's peerType */ - type = laikaS_readByte(&peer->sock); - - /* add peer */ - switch (type) { - case PEER_BOT: { - tPanel_bot *bot = panelB_newBot(pubKey, hostname, ipv4); - panelC_addBot(bot); - break; - } - default: - LAIKA_WARN("unknown peer type? [%d]\n", type); - } -} - -void handleRmvPeer(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { - uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; - uint8_t type; - - /* read newly connected peer's pubKey */ - laikaS_read(&peer->sock, pubKey, crypto_kx_PUBLICKEYBYTES); - - /* read peer's peerType */ - type = laikaS_readByte(&peer->sock); - - /* find peer by pubkey & rmv it */ - switch (type) { - case PEER_BOT: { - tPanel_bot *bot = panelB_getBot(pubKey); - if (bot != NULL) - panelC_rmvBot(bot); - break; - } - default: - LAIKA_WARN("unknown peer type? [%d]\n", type); - } -} - -LAIKAPKT_SIZE panelC_pktSizeTbl[LAIKAPKT_MAXNONE] = { - [LAIKAPKT_HANDSHAKE_RES] = sizeof(uint8_t), - [LAIKAPKT_AUTHENTICATED_ADD_PEER_RES] = crypto_kx_PUBLICKEYBYTES + sizeof(uint8_t) + LAIKA_HOSTNAME_LEN + LAIKA_IPV4_LEN, /* pubkey + peerType + host + ip */ - [LAIKAPKT_AUTHENTICATED_RMV_PEER_RES] = crypto_kx_PUBLICKEYBYTES + sizeof(uint8_t), /* pubkey + peerType */ -}; - -PeerPktHandler panelC_handlerTbl[LAIKAPKT_MAXNONE] = { - [LAIKAPKT_HANDSHAKE_RES] = handleHandshakeResponse, - [LAIKAPKT_AUTHENTICATED_ADD_PEER_RES] = handleAddPeer, - [LAIKAPKT_AUTHENTICATED_RMV_PEER_RES] = handleRmvPeer, -}; - -tPanel_client *panelC_newClient() { - tPanel_client *client = laikaM_malloc(sizeof(tPanel_client)); - size_t _unused; - - laikaP_initPList(&client->pList); - client->peer = laikaS_newPeer( - panelC_handlerTbl, - panelC_pktSizeTbl, - &client->pList, - (void*)client - ); - - /* load authenticated keypair */ - if (sodium_init() < 0) { - panelC_freeClient(client); - LAIKA_ERROR("LibSodium failed to initialize!\n"); - } - - if (sodium_hex2bin(client->pub, crypto_kx_PUBLICKEYBYTES, LAIKA_PUBKEY, strlen(LAIKA_PUBKEY), NULL, &_unused, NULL) != 0) { - panelC_freeClient(client); - LAIKA_ERROR("Failed to init public key!\n"); - } - - if (sodium_hex2bin(client->priv, crypto_kx_SECRETKEYBYTES, LAIKA_PRIVKEY, strlen(LAIKA_PRIVKEY), NULL, &_unused, NULL) != 0) { - panelC_freeClient(client); - LAIKA_ERROR("Failed to init private key!\n"); - } - - /* read cnc's public key into peerPub */ - if (sodium_hex2bin(client->peer->peerPub, crypto_kx_PUBLICKEYBYTES, LAIKA_PUBKEY, strlen(LAIKA_PUBKEY), NULL, &_unused, NULL) != 0) { - panelC_freeClient(client); - LAIKA_ERROR("Failed to init cnc public key!\n"); - } - - return client; -} - -void panelC_freeClient(tPanel_client *client) { - laikaS_freePeer(client->peer); - laikaP_cleanPList(&client->pList); - laikaM_free(client); -} - -void panelC_connectToCNC(tPanel_client *client, char *ip, char *port) { - struct sLaika_socket *sock = &client->peer->sock; - - /* setup socket */ - laikaS_connect(sock, ip, port); - laikaS_setNonBlock(sock); - - laikaP_addSock(&client->pList, sock); - - /* queue handshake request */ - laikaS_startOutPacket(client->peer, LAIKAPKT_HANDSHAKE_REQ); - laikaS_write(sock, LAIKA_MAGIC, LAIKA_MAGICLEN); - laikaS_writeByte(sock, LAIKA_VERSION_MAJOR); - laikaS_writeByte(sock, LAIKA_VERSION_MINOR); - laikaS_write(sock, client->pub, sizeof(client->pub)); /* write public key */ - - /* write stub hostname & ipv4 (since we're a panel/dummy client, cnc doesn't need this information really) */ - laikaS_zeroWrite(sock, LAIKA_HOSTNAME_LEN); - laikaS_zeroWrite(sock, LAIKA_IPV4_LEN); - laikaS_endOutPacket(client->peer); - laikaS_setSecure(client->peer, true); - - 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"); - - /* queue authenticated handshake request */ - laikaS_startOutPacket(client->peer, LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ); - laikaS_writeByte(sock, PEER_AUTH); - laikaS_endOutPacket(client->peer); - - if (!laikaS_handlePeerOut(client->peer)) - LAIKA_ERROR("failed to send handshake request!\n"); -} - -bool panelC_poll(tPanel_client *client, int timeout) { - struct sLaika_pollEvent *evnt; - int numEvents; - - evnt = laikaP_poll(&client->pList, timeout, &numEvents); - - if (numEvents == 0) /* no events? timeout was reached */ - return false; - -LAIKA_TRY - if (evnt->pollIn && !laikaS_handlePeerIn(client->peer)) - goto _CLIENTKILL; - - if (evnt->pollOut && !laikaS_handlePeerOut(client->peer)) - goto _CLIENTKILL; - - if (!evnt->pollIn && !evnt->pollOut) - goto _CLIENTKILL; -LAIKA_CATCH -_CLIENTKILL: - laikaS_kill(&client->peer->sock); -LAIKA_TRYEND - - /* flush pList's outQueue */ - if (client->pList.outCount > 0) { - if (!laikaS_handlePeerOut(client->peer)) - laikaS_kill(&client->peer->sock); - - laikaP_resetOutQueue(&client->pList); - } - - return true; -} - -void panelC_addBot(tPanel_bot *bot) { - tPanel_listItem *bItem; - - /* add to botList tab */ - bItem = panelL_newListItem(panel_botList, NULL, bot->name, NULL, (void*)bot); - - /* link bot with listItem */ - panelB_setItem(bot, bItem); -} - -void panelC_rmvBot(tPanel_bot *bot) { - tPanel_listItem *bItem = bot->item; - - /* free from bot list & then free the bot */ - panelL_freeListItem(panel_botList, bItem); - panelB_freeBot(bot); -} \ No newline at end of file