From de4223170bdb8a1eec3d16803a14ccab15997135 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 21 Feb 2024 20:11:23 +0300 Subject: [PATCH] added ssl support --- C/Makefile | 2 +- C/irc.c | 80 +++++++++++++++++++++++++++++++++++++++++------- C/irc.h | 39 +++++++++++++++++++++-- C/main.c | 23 +++++++------- Python/README.md | 1 - Python/irc.py | 55 --------------------------------- Python/main.py | 28 ----------------- 7 files changed, 117 insertions(+), 111 deletions(-) delete mode 100644 Python/README.md delete mode 100644 Python/irc.py delete mode 100644 Python/main.py diff --git a/C/Makefile b/C/Makefile index 24c6de4..699c1c5 100644 --- a/C/Makefile +++ b/C/Makefile @@ -1,5 +1,5 @@ all: - cc *.c -omain -O0 -g3 -pedantic -Wall -Wextra + cc *.c -omain -O0 -g3 -pedantic -Wall -Wextra -DENABLE_SSL -lcrypto -lssl clean: rm main diff --git a/C/irc.c b/C/irc.c index 476a17e..4e0360a 100644 --- a/C/irc.c +++ b/C/irc.c @@ -9,6 +9,24 @@ #include #include "irc.h" +int IRCC_urecv(IRCC_client *irc) { +#ifdef ENABLE_SSL + if (irc->irc_usingssl) + return SSL_read(irc->irc_ssl, irc->irc_raw, sizeof(irc->irc_raw)); +#endif + + return recv(irc->irc_socket, irc->irc_raw, sizeof(irc->irc_raw), 0); +} + +int IRCC_usend(IRCC_client *irc, off_t bytes) { +#ifdef ENABLE_SSL + if (irc->irc_usingssl) + return SSL_write(irc->irc_ssl, irc->irc_raw, bytes); +#endif + + return send(irc->irc_socket, irc->irc_raw, bytes, 0); +} + int IRCC_connect(IRCC_client *irc, const char *ip, const unsigned int port) { struct hostent *hp = gethostbyname(ip); if (!hp) @@ -38,6 +56,7 @@ int IRCC_connect(IRCC_client *irc, const char *ip, const unsigned int port) { void IRCC_parse_msg(char *tmp, IRCC_client *irc) { irc->irc_raw[strcspn(irc->irc_raw, "\r\n")] = '\0'; + if (tmp != NULL) { //Message char *val = strchr(tmp, ':'); @@ -67,17 +86,14 @@ void IRCC_parse_msg(char *tmp, IRCC_client *irc) { int IRCC_recv(IRCC_client *irc) { memset(irc->irc_raw, '\0', IRCC_MSG_MAX); - irc->irc_channel = NULL; - irc->irc_msg = NULL; - irc->irc_nick = NULL; - int msg_size = recv(irc->irc_socket, irc->irc_raw, sizeof(irc->irc_raw), 0); + int msg_size = IRCC_urecv(irc); if (msg_size == 0 || msg_size == -1) return IRCC_DISCONNECTED; else if (!strncmp(irc->irc_raw, "PING", 4)) { *(strchr(irc->irc_raw, 'I')) = 'O'; - if (send(irc->irc_socket, irc->irc_raw, strlen(irc->irc_raw), 0) == -1) + if (IRCC_usend(irc, strlen(irc->irc_raw)) == -1) return IRCC_ERROR; return IRCC_PING; @@ -87,6 +103,9 @@ int IRCC_recv(IRCC_client *irc) { } int IRCC_parse(IRCC_client *irc) { + irc->irc_channel = NULL; + irc->irc_msg = NULL; + irc->irc_nick = NULL; //Check end of motd if (strstr(irc->irc_raw, "PRIVMSG ") == NULL && strstr(irc->irc_raw, "MOTD")) @@ -129,11 +148,11 @@ int IRCC_parse(IRCC_client *irc) { int IRCC_register(IRCC_client *irc, const char *nickname) { off_t bytes = snprintf(irc->irc_raw, sizeof(irc->irc_raw), "NICK %s\r\n", nickname); - if (send(irc->irc_socket, irc->irc_raw, bytes, 0) == -1) + if (IRCC_usend(irc, bytes) == -1) return IRCC_ERROR; bytes = snprintf(irc->irc_raw, sizeof(irc->irc_raw), "USER %s 0 localhost :%s\r\n", nickname, nickname); - if (send(irc->irc_socket, irc->irc_raw, bytes, 0) == -1) + if (IRCC_usend(irc, bytes) == -1) return IRCC_ERROR; //Motd skip @@ -152,7 +171,7 @@ int IRCC_register(IRCC_client *irc, const char *nickname) { int IRCC_join(IRCC_client *irc, const char *channel, const char *key) { off_t bytes = snprintf(irc->irc_raw, sizeof(irc->irc_raw), "JOIN %s %s\r\n", channel, (key) ? key : ""); - if (send(irc->irc_socket, irc->irc_raw, bytes, 0) == -1) + if (IRCC_usend(irc, bytes) == -1) return IRCC_ERROR; return IRCC_SUCCESS; @@ -160,18 +179,57 @@ int IRCC_join(IRCC_client *irc, const char *channel, const char *key) { int IRCC_send(IRCC_client *irc, const char *channel, const char *msg) { off_t bytes = snprintf(irc->irc_raw, sizeof(irc->irc_raw), "PRIVMSG %s :%s\r\n", channel, msg); - if (send(irc->irc_socket, irc->irc_raw, bytes, 0) == -1) + if (IRCC_usend(irc, bytes) == -1) return IRCC_ERROR; return IRCC_SUCCESS; } -void IRCC_init(IRCC_client *irc) { - irc->irc_msg = irc->irc_nick = irc->irc_channel = NULL; +int IRCC_initssl(IRCC_client *irc, int *ircc_errno) { +#ifdef ENABLE_SSL + OpenSSL_add_all_algorithms(); + + if (SSL_library_init() < 0) { + *ircc_errno = IRCC_SSL_INIT; + return IRCC_ERROR; + } + + irc->irc_sslmethod = (SSL_METHOD *)SSLv23_client_method(); + irc->irc_sslctx = SSL_CTX_new(irc->irc_sslmethod); + if (irc->irc_sslctx == NULL) { + *ircc_errno = IRCC_SSL_METHOD; + return IRCC_ERROR; + } + + SSL_CTX_set_options(irc->irc_sslctx, SSL_OP_NO_SSLv2); + irc->irc_ssl = SSL_new(irc->irc_sslctx); + + SSL_set_fd(irc->irc_ssl, irc->irc_socket); + if (SSL_connect(irc->irc_ssl) != 1) { + *ircc_errno = IRCC_SSL_SESSION; + return IRCC_ERROR; + } + + irc->irc_usingssl = 1; + +#else + (void)irc; + *ircc_errno = 0; +#endif + + return IRCC_SUCCESS; } void IRCC_close(IRCC_client *irc) { close(irc->irc_socket); irc->irc_msg = irc->irc_nick = irc->irc_channel = NULL; + +#ifdef ENABLE_SSL + if (!irc->irc_usingssl) + return; + + SSL_free(irc->irc_ssl); + SSL_CTX_free(irc->irc_sslctx); +#endif } diff --git a/C/irc.h b/C/irc.h index cc880e3..6a05c21 100644 --- a/C/irc.h +++ b/C/irc.h @@ -1,16 +1,22 @@ /* LICENSE: WTFPL - Simple libary for working with ipv4 irc servers + Simple library for working with ipv4 irc servers Dont support: - ssl ddc ipv6 motd */ +#ifndef _IRCC_H +#define _IRCC_H + #define IRCC_MSG_MAX 512 #define IRCC_PING_TIMEOUT 600 +#ifdef ENABLE_SSL +#include +#endif + enum { IRCC_NICK = 1, IRCC_PRIVMSG, @@ -26,6 +32,19 @@ enum { IRCC_SUCCESS }; +enum { + IRCC_SSL_INIT = 1, + IRCC_SSL_METHOD, + IRCC_SSL_SESSION +}; + +static const char *IRCC_errno[] = { + "", + "Could not initialize the SSL library", + "Unable to create a new SSL context struct", + "Could not build a SSL session" +}; + typedef struct { int irc_socket; @@ -33,6 +52,14 @@ typedef struct { char *irc_msg; char *irc_channel; char *irc_nick; + +#ifdef ENABLE_SSL + int irc_usingssl; + + SSL_METHOD *irc_sslmethod; + SSL_CTX *irc_sslctx; + SSL *irc_ssl; +#endif } IRCC_client; int IRCC_connect(IRCC_client *irc, const char *ip, const unsigned int port); @@ -41,5 +68,11 @@ int IRCC_parse(IRCC_client *irc); int IRCC_join(IRCC_client *irc, const char *channel, const char *key); int IRCC_send(IRCC_client *irc, const char *msg, const char *channel); int IRCC_register(IRCC_client *irc, const char *nickname); -void IRCC_init(IRCC_client *irc); +int IRCC_initssl(IRCC_client *irc, int *ircc_errno); void IRCC_close(IRCC_client *irc); + +//u - mean universal. Functions uses internal fields in structure +int IRCC_usend(IRCC_client *irc, off_t bytes); +int IRCC_urecv(IRCC_client *irc); + +#endif diff --git a/C/main.c b/C/main.c index f760ba5..28bf65a 100644 --- a/C/main.c +++ b/C/main.c @@ -5,17 +5,16 @@ #include "irc.h" //Config -#define HOST "192.168.0.184" -#define PORT 6667 +#define HOST "irc.rizon.net" +#define PORT 6697 #define NICK "tester134" -char *channels[] = {"#test"}; - +char *channels[] = {"#testssl"}; #define CHECK_NULL() (client.irc_nick != NULL && client.irc_channel != NULL && client.irc_msg != NULL) IRCC_client client; -void die(char *msg) { - puts(msg); +void die(const char *msg) { + perror(msg); IRCC_close(&client); exit(1); } @@ -30,7 +29,7 @@ void recvinfo(void) { //Print if (CHECK_NULL() && irc_status == IRCC_PRIVMSG) - printf("[%s %s] %s\n", client.irc_channel, client.irc_nick, client.irc_msg); + printf("%s\n", client.irc_msg); else if (client.irc_nick != NULL && client.irc_msg != NULL && irc_status == IRCC_NICK) printf("[N] %s is know as %s\n", client.irc_nick, client.irc_msg); @@ -47,17 +46,17 @@ void recvinfo(void) { } int main(void) { - - //512 - size of raw buffer (max irc) - IRCC_init(&client); int status = IRCC_connect(&client, HOST, PORT); if (status == IRCC_ERROR) die("Conn refused"); - //Register + int ie = 0; + if (IRCC_initssl(&client, &ie) == IRCC_ERROR) + die(IRCC_errno[ie]); + + //Register and skip motd IRCC_register(&client, NICK); - //Recv motd and join in channel sleep(5); for (size_t i = 0; i < sizeof(channels) / sizeof(char *); i++) { if (channels[i] == NULL) diff --git a/Python/README.md b/Python/README.md deleted file mode 100644 index 955c919..0000000 --- a/Python/README.md +++ /dev/null @@ -1 +0,0 @@ -Delete me diff --git a/Python/irc.py b/Python/irc.py deleted file mode 100644 index 7c1070d..0000000 --- a/Python/irc.py +++ /dev/null @@ -1,55 +0,0 @@ -import socket -import time -import sys - -class IRC: - def __init__(self, channel, code): - self.channel = channel - self.sock = socket.socket() - self.code = code - - self.sender = {"ip":"", "nickname":""} - self.data = {"type":""} - - def connect(self, host, nick): - self.sock.connect(host) - - self.sock.send(f"USER {nick} 0 0 {nick}\r\n".encode(self.code)) - self.sock.send(f"NICK {nick}\r\n".encode(self.code)) - time.sleep(7) - self.sock.send(f"JOIN {self.channel}\r\n".encode(self.code)) - - def recv(self, size): - try: - data = self.sock.recv(size).decode() - except UnicodeDecodeError: - return None - - if len(data) == 0: - self.sock.close() - raise BrokenPipeError("Disconnected") - - if "PING" in data.split(":")[0]: - self.sock.send(f"PONG {data.split()[-1]}\r\n".encode()) - return data - - def parser(self, data): - data = data.split(" ", 3) - self.sender["ip"] = data[0].split("@", 1)[-1] - self.sender["nickname"] = data[0].split("!", 1)[0][1:] - - if data[1] == "PRIVMSG": - self.data["channel"] = data[2] - self.data["msg"] = data[-1][1:].strip() - self.data["type"] = "PRIVMSG" - - elif data[1] == "JOIN": - self.data["type"] = "JOIN" - elif data[1] == "PART": - self.data["type"] = "PART" - - def sendMSG(self, msg, channel): - self.sock.send(f"PRIVMSG {channel} :{msg}\r\n".encode(self.code)) - - def sendRAW(self, msg): - self.sock.send(f"{msg}\r\n".encode(self.code)) diff --git a/Python/main.py b/Python/main.py deleted file mode 100644 index a5b2453..0000000 --- a/Python/main.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/python3 -import sys -import time -from irc import IRC - -def main(): - main = IRC("#mainchannel", "cp1251") - main.connect(("irc..ru", 6667), "tester") - - while True: - data = main.recv(512) - if data is None: - continue - - main.parser(data) - print(main.sender) - print(main.data) - -if __name__ == "__main__": - while True: - try: - main() - - except KeyboardInterrupt: - break - - except: - pass