diff --git a/lib/irc.h b/lib/irc.h index 87ffbf6..3dac429 100755 --- a/lib/irc.h +++ b/lib/irc.h @@ -15,20 +15,37 @@ #include "db.h" #ifdef _WIN32 +#define OUTBUF_SIZE DEFAULT_BUFLEN +#define INBUF_SIZE DEFAULT_BUFLEN #include +#define SECURITY_WIN32 +#include +#include +#include + #else +#define OUTBUF_SIZE 1200000 +#define INBUF_SIZE 1200000 #include #include #include #endif -#define OUTBUF_SIZE 1200000 -#define INBUF_SIZE 1200000 struct irc_conn { #ifdef _WIN32 SOCKET srv_fd; + + SCHANNEL_CRED schannelCred; + CtxtHandle ctxtHand; + SecBufferDesc outBufferDesc; + SecBuffer outBuffer; + SecBufferDesc inBufferDesc; + SecBuffer inBuffer; + SECURITY_STATUS secStatus; + DWORD dwSSPIFlags; + #else FILE *srv_fd; int ssl_fd; diff --git a/lib/module.h b/lib/module.h index 1da0d40..4f1c9e1 100755 --- a/lib/module.h +++ b/lib/module.h @@ -4,9 +4,6 @@ #include "irc.h" #include "events.h" -#ifdef _WIN32 -#include -#endif struct module { char name[25]; diff --git a/src/irc.c b/src/irc.c index 98a3a1e..976d468 100755 --- a/src/irc.c +++ b/src/irc.c @@ -19,9 +19,6 @@ #include #ifdef _WIN32 -#include -#include -#include #define FDOPEN _fdopen #define SETBUF setbuf #else @@ -45,42 +42,16 @@ void irc_connect(struct irc_conn *bot) struct sockaddr_in server; struct hostent *host; - // SChannel stuff - SCHANNEL_CRED schannelCred; - CtxtHandle ctxtHandle; - SecBufferDesc outBufferDesc; - SecBuffer outBuffer; - SECURITY_STATUS secStatus; - DWORD dwSSPIFlags; - - if (bot->use_ssl) - { - ZeroMemory(&schannelCred, sizeof(schannelCred)); - ZeroMemory(&ctxtHandle, sizeof(ctxtHandle)); - ZeroMemory(&outBufferDesc, sizeof(outBufferDesc)); - ZeroMemory(&outBuffer, sizeof(outBuffer)); - - // init outbufferdesc and outbuffer - outBufferDesc.ulVersion = SECBUFFER_VERSION; - outBufferDesc.cBuffers = 1; - outBufferDesc.pBuffers = &outBuffer; - outBuffer.BufferType = SECBUFFER_TOKEN; - outBuffer.cbBuffer = 0; - outBuffer.pvBuffer = NULL; - - - // setup the credentials - schannelCred.dwVersion = SCHANNEL_CRED_VERSION; - schannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT; - schannelCred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_NO_SYSTEM_MAPPER; - schannelCred.cCreds = 1; - schannelCred.paCred = &bot->cred; - schannelCred.hRootStore = NULL; - schannelCred.dwMinimumCipherStrength = 128; - schannelCred.dwMaximumCipherStrength = 128; - schannelCred.dwSessionLifespan = 0; - } + SCHANNEL_CEAD cred = { + .dwVersion = SCHANNEL_CRED_VERSION, + .dwFlags = SCH_USE_STRONG_CRYPTO + | SCH_CRED_AUTO_CRED_VALIDATION + | SCH_CRED_NO_DEFAULT_CREDS + .grbitEnabledProtocols = SP_PROT_TLS1_2, + }; + CtxtHandle *context = NULL; + int res = 0; sprintf(titlebuf, "xbot [connecting]: %s:%s", bot->host, bot->port); SetConsoleTitle(titlebuf); @@ -132,22 +103,17 @@ void irc_connect(struct irc_conn *bot) if (bot->use_ssl) { - // perform the handshake - secStatus = InitalizeSecurityContet(NULL, NULL, NULL, dwSSPIFlags, 0, 0, NULL, 0, &ctxtHandle, &outBufferDesc, NULL, NULL); - if (secStatus != SEC_I_CONTINUE_NEEDED) + if (AcquireCredentialsHandle(NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL, &bot->cred, NULL) != SEC_E_OK) { - eprint("Error: Handshake failed\n"); - exit(EXIT_FAILURE); - } - - - // send the handshake - if (send(bot->srv_fd, outBuffer.pvBuffer, outBuffer.cbBuffer, 0) == SOCKET_ERROR) - { - eprint("Error: Handshake failed\n"); - exit(EXIT_FAILURE); + eprint("Error: Cannot acquire credentials handle\n"); + closesocket(bot->srv_fd); + WSACleanup(); + + return; } + bot->recvCount = bot->usedCount = bot->availableCount = 0; + bot->decrypted = NULL; } sprintf(titlebuf, "xbot [connected]: %s:%s", bot->host, bot->port); diff --git a/src/main.c b/src/main.c index 5b7fc87..59dc58f 100755 --- a/src/main.c +++ b/src/main.c @@ -203,28 +203,62 @@ int main(int argc, char **argv) #ifdef _WIN32 if (FD_ISSET(bot.srv_fd, &rd)) { - bytesRecv = recv(bot.srv_fd, bot.in, INBUF_SIZE, 0); - if (bytesRecv == SOCKET_ERROR) - { - eprint("Error receiving data: %d\n", WSAGetLastError()); - closesocket(bot.srv_fd); - WSACleanup(); - - return -1; - } - - if (bytesRecv == 0) + if (bot->use_ssl) { - eprint("xbot: remote host closed connection\n"); - return 0; + bytesRecv = recv(bot.srv_fd, bot.inBuffer.pvBuffer, DEFAULT_BUFLEN, 0); + if (bytesRecv == SOCKET_ERROR) + { + eprint("Error receiving data: %d\n", WSAGetLastError()); + closesocket(bot.srv_fd); + WSACleanup(); + + return -1; + } + + if (bytesRecv == 0) + { + eprint("xbot: remote host closed connection\n"); + return 0; + } + + bot.inBuffer.cbBuffer = bytesRecv; + + secStatus = DecryptMessage(&bot->ctxtHandle, &bot->inBuffer, 0, NULL); + if (secStatus != SEC_E_OK) + { + eprint("xbot: error on DecryptMessage()\n"); + return -1; + } + + strlcpy(bot.in, bot.inBuffer.pvBuffer, bot.inBuffer.cbBuffer); + bot.in[bot.inBuffer.cbBuffer] = '\0'; + + printf("recv: %s\r\n", bot.in); + } + else + { + bytesRecv = recv(bot.srv_fd, bot.in, INBUF_SIZE, 0); + if (bytesRecv == SOCKET_ERROR) + { + eprint("Error receiving data: %d\n", WSAGetLastError()); + closesocket(bot.srv_fd); + WSACleanup(); + + return -1; + } + + if (bytesRecv == 0) + { + eprint("xbot: remote host closed connection\n"); + return 0; + } + + bot.in[bytesRecv] = '\0'; + + printf("recv: %s\r\n", bot.in); } - bot.in[bytesRecv] = '\0'; - - printf("recv: %s\r\n", bot.in); - // split bot.in into lines by \r\n and parse each one - while (1) { // remove \r