summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/db_plain.cpp3
-rw-r--r--src/main.c12
-rw-r--r--src/misc.c15
-rw-r--r--src/modules/CMakeLists.txt1
-rw-r--r--src/modules/ssl/m_ssl.cpp150
5 files changed, 175 insertions, 6 deletions
diff --git a/src/core/db_plain.cpp b/src/core/db_plain.cpp
index 65f936650..0ae6c47f8 100644
--- a/src/core/db_plain.cpp
+++ b/src/core/db_plain.cpp
@@ -556,8 +556,7 @@ class DBPlain : public Module
void BackupDatabase()
{
/* Do not backup a database that doesn't exist */
- struct stat DBInfo;
- if (stat(DatabaseFile.c_str(), &DBInfo))
+ if (!IsFile(DatabaseFile))
{
return;
}
diff --git a/src/main.c b/src/main.c
index 234a2e023..4c91fcde2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -389,10 +389,16 @@ std::string GetFullProgDir(char *argv0)
static bool Connect()
{
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnPreServerConnect, OnPreServerConnect());
+ if (MOD_RESULT != EVENT_CONTINUE)
+ {
+ return (MOD_RESULT == EVENT_ALLOW ? true : false);
+ }
+
/* Connect to the remote server */
- std::list<Uplink *>::iterator curr_uplink = Config.Uplinks.begin(), end_uplink = Config.Uplinks.end();
int servernum = 1;
- for (; curr_uplink != end_uplink; ++curr_uplink, ++servernum)
+ for (std::list<Uplink *>::iterator curr_uplink = Config.Uplinks.begin(); curr_uplink != Config.Uplinks.end(); ++curr_uplink, ++servernum)
{
uplink_server = *curr_uplink;
@@ -472,8 +478,6 @@ int main(int ac, char **av, char **envp)
if ((i = init_secondary(ac, av)) != 0)
return i;
- FOREACH_MOD(I_OnPreServerConnect, OnPreServerConnect());
-
/* If the first connect fails give up, don't sit endlessly trying to reconnect */
if (!Connect())
fatal_perror("Can't connect to any servers");
diff --git a/src/misc.c b/src/misc.c
index 338737007..9b535b1ab 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -27,6 +27,21 @@ struct arc4_stream {
/*************************************************************************/
+/** Check if a file exists
+ * @param filename The file
+ * @return true if the file exists, false if it doens't
+ */
+bool IsFile(const std::string &filename)
+{
+ struct stat fileinfo;
+ if (!stat(filename.c_str(), &fileinfo))
+ {
+ return true;
+ }
+
+ return false;
+}
+
/**
* toupper: Like the ANSI functions, but make sure we return an
* int instead of a (signed) char.
diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt
index ad66663c3..6cb5b5612 100644
--- a/src/modules/CMakeLists.txt
+++ b/src/modules/CMakeLists.txt
@@ -58,6 +58,7 @@ endforeach(SRC)
file(GLOB MODULES_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*")
remove_item_from_list(MODULES_FILES "CMakeFiles")
remove_item_from_list(MODULES_FILES "mysql")
+remove_item_from_list(MODULES_FILES "ssl")
# Iterate through this directory searching for subdirectories, and creating modules for those subdirectories
foreach(FILE ${MODULES_FILES})
diff --git a/src/modules/ssl/m_ssl.cpp b/src/modules/ssl/m_ssl.cpp
new file mode 100644
index 000000000..8036de6ce
--- /dev/null
+++ b/src/modules/ssl/m_ssl.cpp
@@ -0,0 +1,150 @@
+/* RequiredLibraries: ssl,crypt */
+
+#include "module.h"
+
+#include <openssl/bio.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+
+#define CERTFILE "anope.cert"
+#define KEYFILE "anope.key"
+
+static SSL_CTX *ctx;
+
+class SSLSocket : public Socket
+{
+ private:
+ SSL *sslsock;
+
+ int RecvInternal(char *buf, size_t sz) const
+ {
+ return SSL_read(sslsock, buf, sz);
+ }
+
+ int SendInternal(const std::string &buf) const
+ {
+ return SSL_write(sslsock, buf.c_str(), buf.size());
+ }
+ public:
+ SSLSocket(const std::string &nTargetHost, int nPort, const std::string &nBindHost = "", bool nIPv6 = false) : Socket(nTargetHost, nPort, nBindHost, nIPv6)
+ {
+ sslsock = SSL_new(ctx);
+
+ if (!sslsock)
+ throw CoreException("Unable to initialize SSL socket");
+
+ SSL_set_connect_state(sslsock);
+ SSL_set_fd(sslsock, Sock);
+ SSL_connect(sslsock);
+
+ UplinkSock = this;
+ }
+
+ ~SSLSocket()
+ {
+ SSL_shutdown(sslsock);
+ SSL_free(sslsock);
+
+ UplinkSock = NULL;
+ }
+
+ bool Read(const std::string &buf)
+ {
+ process(buf);
+ return true;
+ }
+};
+
+class SSLModule : public Module
+{
+ public:
+ SSLModule(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(SUPPORTED);
+
+ SSL_load_error_strings();
+ SSLeay_add_ssl_algorithms();
+
+ ctx = SSL_CTX_new(SSLv23_client_method());
+
+ if (!ctx)
+ {
+ throw ModuleException("Error initializing SSL CTX");
+ }
+
+ if (IsFile(CERTFILE))
+ {
+ if (!SSL_CTX_use_certificate_file(ctx, CERTFILE, SSL_FILETYPE_PEM))
+ {
+ SSL_CTX_free(ctx);
+ throw ModuleException("Error loading certificate");
+ }
+ }
+ else
+ {
+ Alog() << "m_ssl: No certificate file found";
+ }
+
+ if (IsFile(KEYFILE))
+ {
+ if (!SSL_CTX_use_PrivateKey_file(ctx, KEYFILE, SSL_FILETYPE_PEM))
+ {
+ SSL_CTX_free(ctx);
+ throw ModuleException("Error loading private key");
+ }
+ }
+ else
+ {
+ if (IsFile(CERTFILE))
+ {
+ SSL_CTX_free(ctx);
+ throw ModuleException("Error loading private key - file not found");
+ }
+ else
+ {
+ Alog() << "m_ssl: No private key found";
+ }
+ }
+
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
+ SSL_CTX_set_options(ctx, SSL_OP_TLS_ROLLBACK_BUG | SSL_OP_ALL);
+// SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, always_accept_verify_cb);
+
+ ModuleManager::Attach(I_OnPreServerConnect, this);
+ }
+
+ ~SSLModule()
+ {
+ SSL_CTX_free(ctx);
+ }
+
+ EventReturn OnPreServerConnect()
+ {
+ int servernum = 1;
+ for (std::list<Uplink *>::iterator curr_uplink = Config.Uplinks.begin(); curr_uplink != Config.Uplinks.end(); ++curr_uplink, ++servernum)
+ {
+ uplink_server = *curr_uplink;
+
+ try
+ {
+ new SSLSocket(uplink_server->host, uplink_server->port, Config.LocalHost ? Config.LocalHost : "", uplink_server->ipv6);
+ }
+ catch (SocketException& ex)
+ {
+ Alog() << "Unable to connect to server" << servernum << " (" << uplink_server->host << ":" << uplink_server->port << "), " << ex.GetReason();
+ continue;
+ }
+
+ Alog() << "Connected to Server " << servernum << " (" << uplink_server->host << ":" << uplink_server->port << ")";
+ return EVENT_ALLOW;
+ }
+
+ return EVENT_STOP;
+ }
+};
+
+MODULE_INIT(SSLModule)