src/ChanNode.c \
src/IRCParser.c \
src/ClientSocket.c \
+ src/ssl.c \
src/UserNode.c \
src/ChanUser.c \
src/ModeNode.c \
[WINSOCK_LIBS=''])
AC_SUBST([WINSOCK_LIBS])
+AC_CHECK_LIB(ssl, SSL_read, [
+ AC_CHECK_LIB(crypto, X509_new, [
+ AC_CHECK_HEADERS(openssl/ssl.h openssl/err.h openssl/rand.h, [
+ LIBS="$LIBS -lssl -lcrypto"
+ AC_DEFINE([HAVE_SSL], 1, [Define if you are using SSL])
+ ])
+ ])
+])
+
# Checks for header files.
AC_CHECK_HEADERS([arpa/inet.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h windows.h winsock2.h])
#include "IRCQueue.h"
#include "WHOHandler.h"
#include "HandleInfoHandler.h"
+#include "ssl.h"
struct socket_list {
struct ClientSocket *data;
client->flags |= SOCKET_FLAG_CONNECTED | SOCKET_FLAG_RECONNECT;
client->connection_time = time(0);
+
+ if(client->flags & SOCKET_FLAG_SSL) {
+ ssl_connect(client);
+ }
+
+
//send the IRC Headers
char sendBuf[512];
int len;
client->flags |= SOCKET_FLAG_CONNECTED | SOCKET_FLAG_RECONNECT;
client->connection_time = time(0);
+ if(client->flags & SOCKET_FLAG_SSL) {
+ ssl_connect(client);
+ }
+
//send the IRC Headers
char sendBuf[512];
int len;
if(client == NULL) return 0;
if((client->flags & SOCKET_FLAG_CONNECTED))
close(client->sock);
+ if(client->flags & SOCKET_FLAG_SSL)
+ ssl_disconnect(client);
struct ClientSocket *sock, *last_sock = NULL;
for (sock = sockets->data; sock; sock = sock->next) {
if(sock == client) {
int write_socket_force(struct ClientSocket *client, char* msg, int len) {
printf("[send %d] %s", len, msg);
- #ifdef WIN32
- send(client->sock, msg, len, 0);
- #else
- write(client->sock, msg, len);
- #endif
+ if(!(client->flags & SOCKET_FLAG_SSL) || ssl_write(client, msg, len) == -2) {
+ #ifdef WIN32
+ send(client->sock, msg, len, 0);
+ #else
+ write(client->sock, msg, len);
+ #endif
+ }
client->traffic_out += len;
return 1;
}
for (sock = sockets->data; sock; sock = sock->next) {
if((sock->flags & SOCKET_FLAG_CONNECTED) && FD_ISSET(sock->sock, &fds)) {
if(sock->bufferpos != 0) {
- #ifdef WIN32
- bytes = recv(sock->sock, buffer, sizeof(buffer), 0);
- #else
- bytes = read(sock->sock, buffer, sizeof(buffer));
- #endif
+ if(!(sock->flags & SOCKET_FLAG_SSL) || (bytes = ssl_read(sock, buffer, sizeof(buffer))) == -2) {
+ #ifdef WIN32
+ bytes = recv(sock->sock, buffer, sizeof(buffer), 0);
+ #else
+ bytes = read(sock->sock, buffer, sizeof(buffer));
+ #endif
+ }
if(bytes > 0) {
for(i = 0; i < bytes; i++) {
if(sock->bufferpos + i == BUF_SIZ*2) break; //buffer overflow
sock->bufferpos += i;
}
} else {
- #ifdef WIN32
- bytes = recv(sock->sock, sock->buffer, sizeof(sock->buffer), 0);
- #else
- bytes = read(sock->sock, sock->buffer, sizeof(sock->buffer));
- #endif
+ if(!(sock->flags & SOCKET_FLAG_SSL) || (bytes = ssl_read(sock, buffer, sizeof(buffer))) == -2) {
+ #ifdef WIN32
+ bytes = recv(sock->sock, sock->buffer, sizeof(sock->buffer), 0);
+ #else
+ bytes = read(sock->sock, sock->buffer, sizeof(sock->buffer));
+ #endif
+ }
if(bytes > 0)
sock->bufferpos = bytes;
}
bot_disconnect(sock);
if(sock->queue)
queue_destroy(sock);
+ close(sock->sock);
+ if(sock->flags & SOCKET_FLAG_SSL)
+ ssl_disconnect(sock);
} else {
sock->traffic_in += bytes;
int used = parse_lines(sock, sock->buffer, sock->bufferpos);
next = client->next;
if((client->flags & SOCKET_FLAG_CONNECTED))
close(client->sock);
+ if(client->flags & SOCKET_FLAG_SSL)
+ ssl_disconnect(client);
if(client->queue)
queue_destroy(client);
free(client->host);
#define SOCKET_FLAG_PREFERRED 0x08 /* prefered bot to send datas to the IRC World (NOTICE's WHO's etc pp) */
#define SOCKET_FLAG_USE_QUEUE 0x10
#define SOCKET_FLAG_RECONNECT 0x20
+#define SOCKET_FLAG_SSL 0x40
#define BUF_SIZ 512
struct UserNode;
struct trigger_cache;
+struct SSLConnection;
struct ClientSocket {
int sock;
unsigned long traffic_in;
unsigned long traffic_out;
time_t connection_time;
+ struct SSLConnection *sslconn;
struct BotQueue *queue;
MYSQL_RES *res, *res2;
MYSQL_ROW row;
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client = create_socket(row[3], atoi(row[4]), row[5], row[0], row[1], row[2]);
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
+ client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
client->botid = BOTID;
client->clientid = atoi(row[7]);
connect_socket(client);
MYSQL_RES *res, *res2;
MYSQL_ROW row;
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client = create_socket(row[3], atoi(row[4]), row[5], row[0], row[1], row[2]);
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
+ client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
client->botid = BOTID;
client->clientid = atoi(row[7]);
connect_socket(client);
MYSQL_RES *res, *res2;
MYSQL_ROW row;
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client = create_socket(row[3], atoi(row[4]), row[5], row[0], row[1], row[2]);
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
+ client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
client->botid = BOTID;
client->clientid = atoi(row[7]);
connect_socket(client);
MYSQL_RES *res, *res2;
MYSQL_ROW row;
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client = create_socket(row[3], atoi(row[4]), row[5], row[0], row[1], row[2]);
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
+ client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
client->botid = BOTID;
client->clientid = atoi(row[7]);
connect_socket(client);
#include "DBHelper.h"
#include "commands.h"
#include "ConfigParser.h"
+#include "ssl.h"
time_t start_time;
static int running;
queue_init();
init_lang();
+ ssl_init();
init_parser();
init_UserNode();
init_ChanNode();
*/
#ifndef _main_h
#define _main_h
+#include "../config.h"
#define NEONSERV_VERSION "5.2"
#define VERSION_PATCHLEVEL 414
--- /dev/null
+/* ssl.c - NeonServ v5.2
+ * Copyright (C) 2011 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ssl.h"
+#include "ClientSocket.h"
+
+void ssl_init() {
+#ifdef HAVE_SSL
+ SSL_library_init();
+#endif
+}
+
+void ssl_connect(struct ClientSocket *client) {
+#ifdef HAVE_SSL
+ client->sslconn = NULL;
+ if(!(client->flags & SOCKET_FLAG_CONNECTED)) return;
+ struct SSLConnection *sslconn = malloc(sizeof(*sslconn));
+ sslconn->sslContext = SSL_CTX_new(SSLv23_client_method());
+ if(!sslconn->sslContext) goto ssl_connect_err;
+ sslconn->sslHandle = SSL_new(sslconn->sslContext);
+ if(!sslconn->sslHandle) goto ssl_connect_err;
+ if(!SSL_set_fd(sslconn->sslHandle, client->sock)) goto ssl_connect_err;
+ if(SSL_connect(sslconn->sslHandle) != 1) goto ssl_connect_err;
+ client->sslconn = sslconn;
+ssl_connect_err:
+ free(sslconn);
+#endif
+}
+
+void ssl_disconnect(struct ClientSocket *client) {
+#ifdef HAVE_SSL
+ if(!client->sslconn) return;
+ SSL_shutdown(client->sslconn->sslHandle);
+ SSL_free(client->sslconn->sslHandle);
+ SSL_CTX_free(client->sslconn->sslContext);
+ free(client->sslconn);
+ client->sslconn = NULL;
+#endif
+}
+
+int ssl_read(struct ClientSocket *client, char *buffer, int len) {
+#ifdef HAVE_SSL
+ if(!client->sslconn) return -2;
+ return SSL_read(client->sslconn->sslHandle, buffer, len);
+#endif
+ return -2;
+}
+
+int ssl_write(struct ClientSocket *client, char *buffer, int len) {
+#ifdef HAVE_SSL
+ if(!client->sslconn) return -2;
+ return SSL_write(client->sslconn->sslHandle, buffer, len);
+#endif
+ return -2;
+}
\ No newline at end of file
--- /dev/null
+/* ssl.h - NeonServ v5.2
+ * Copyright (C) 2011 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _ssl_h
+#define _ssl_h
+
+#include "main.h"
+
+struct ClientSocket;
+
+#ifdef HAVE_SSL
+#include <openssl/rand.h>
+#include <openssl/ssl.h>
+
+struct SSLConnection {
+ SSL *sslHandle;
+ SSL_CTX *sslContext;
+};
+#else
+struct SSLConnection {
+ //just unused
+};
+#endif
+
+void ssl_init();
+void ssl_connect(struct ClientSocket *client);
+void ssl_disconnect(struct ClientSocket *client);
+int ssl_read(struct ClientSocket *client, char *buffer, int len);
+int ssl_write(struct ClientSocket *client, char *buffer, int len);
+
+#endif
\ No newline at end of file