00001
00002
00003 #include "module.h"
00004 #include "ssl.h"
00005
00006 #define OPENSSL_NO_SHA512
00007 #include <openssl/bio.h>
00008 #include <openssl/ssl.h>
00009 #include <openssl/err.h>
00010 #include <openssl/crypto.h>
00011 #include <openssl/evp.h>
00012
00013 static SSL_CTX *server_ctx, *client_ctx;
00014
00015 class MySSLService : public SSLService
00016 {
00017 public:
00018 MySSLService(Module *o, const Anope::string &n);
00019
00023 void Init(Socket *s) anope_override;
00024 };
00025
00026 class SSLSocketIO : public SocketIO
00027 {
00028 public:
00029
00030 SSL *sslsock;
00031
00034 SSLSocketIO();
00035
00042 int Recv(Socket *s, char *buf, size_t sz) anope_override;
00043
00049 int Send(Socket *s, const char *buf, size_t sz) anope_override;
00050
00055 ClientSocket *Accept(ListenSocket *s) anope_override;
00056
00061 SocketFlag FinishAccept(ClientSocket *cs) anope_override;
00062
00068 void Connect(ConnectionSocket *s, const Anope::string &target, int port) anope_override;
00069
00074 SocketFlag FinishConnect(ConnectionSocket *s) anope_override;
00075
00078 void Destroy() anope_override;
00079 };
00080
00081 class SSLModule;
00082 static SSLModule *me;
00083 class SSLModule : public Module
00084 {
00085 static int AlwaysAccept(int, X509_STORE_CTX *)
00086 {
00087 return 1;
00088 }
00089
00090 Anope::string certfile, keyfile;
00091
00092 public:
00093 MySSLService service;
00094
00095 SSLModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), service(this, "ssl")
00096 {
00097 me = this;
00098
00099 this->SetAuthor("Anope");
00100 this->SetPermanent(true);
00101
00102 SSL_library_init();
00103 SSL_load_error_strings();
00104
00105 client_ctx = SSL_CTX_new(SSLv23_client_method());
00106 server_ctx = SSL_CTX_new(SSLv23_server_method());
00107
00108 if (!client_ctx || !server_ctx)
00109 throw ModuleException("Error initializing SSL CTX");
00110
00111 this->OnReload();
00112
00113 if (Anope::IsFile(this->certfile.c_str()))
00114 {
00115 if (!SSL_CTX_use_certificate_file(client_ctx, this->certfile.c_str(), SSL_FILETYPE_PEM) || !SSL_CTX_use_certificate_file(server_ctx, this->certfile.c_str(), SSL_FILETYPE_PEM))
00116 {
00117 SSL_CTX_free(client_ctx);
00118 SSL_CTX_free(server_ctx);
00119 throw ModuleException("Error loading certificate");
00120 }
00121 else
00122 Log(LOG_DEBUG) << "m_ssl: Successfully loaded certificate " << this->certfile;
00123 }
00124 else
00125 Log() << "Unable to open certificate " << this->certfile;
00126
00127 if (Anope::IsFile(this->keyfile.c_str()))
00128 {
00129 if (!SSL_CTX_use_PrivateKey_file(client_ctx, this->keyfile.c_str(), SSL_FILETYPE_PEM) || !SSL_CTX_use_PrivateKey_file(server_ctx, this->keyfile.c_str(), SSL_FILETYPE_PEM))
00130 {
00131 SSL_CTX_free(client_ctx);
00132 SSL_CTX_free(server_ctx);
00133 throw ModuleException("Error loading private key");
00134 }
00135 else
00136 Log(LOG_DEBUG) << "m_ssl: Successfully loaded private key " << this->keyfile;
00137 }
00138 else
00139 {
00140 if (Anope::IsFile(this->certfile.c_str()))
00141 {
00142 SSL_CTX_free(client_ctx);
00143 SSL_CTX_free(server_ctx);
00144 throw ModuleException("Error loading private key " + this->keyfile + " - file not found");
00145 }
00146 else
00147 Log() << "Unable to open private key " << this->keyfile;
00148 }
00149
00150 SSL_CTX_set_mode(client_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
00151 SSL_CTX_set_mode(server_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
00152
00153 SSL_CTX_set_verify(client_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, SSLModule::AlwaysAccept);
00154 SSL_CTX_set_verify(server_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, SSLModule::AlwaysAccept);
00155
00156 Anope::string context_name = "Anope";
00157 SSL_CTX_set_session_id_context(client_ctx, reinterpret_cast<const unsigned char *>(context_name.c_str()), context_name.length());
00158 SSL_CTX_set_session_id_context(server_ctx, reinterpret_cast<const unsigned char *>(context_name.c_str()), context_name.length());
00159
00160 ModuleManager::Attach(I_OnReload, this);
00161 ModuleManager::Attach(I_OnPreServerConnect, this);
00162 }
00163
00164 ~SSLModule()
00165 {
00166 for (std::map<int, Socket *>::const_iterator it = SocketEngine::Sockets.begin(), it_end = SocketEngine::Sockets.end(); it != it_end;)
00167 {
00168 Socket *s = it->second;
00169 ++it;
00170
00171 if (dynamic_cast<SSLSocketIO *>(s->io))
00172 delete s;
00173 }
00174
00175 SSL_CTX_free(client_ctx);
00176 SSL_CTX_free(server_ctx);
00177 }
00178
00179 void OnReload() anope_override
00180 {
00181 ConfigReader config;
00182
00183 this->certfile = config.ReadValue("ssl", "cert", "data/anope.crt", 0);
00184 this->keyfile = config.ReadValue("ssl", "key", "data/anope.key", 0);
00185 }
00186
00187 void OnPreServerConnect() anope_override
00188 {
00189 ConfigReader config;
00190
00191 if (config.ReadFlag("uplink", "ssl", "no", Anope::CurrentUplink))
00192 {
00193 this->service.Init(UplinkSock);
00194 }
00195 }
00196 };
00197
00198 MySSLService::MySSLService(Module *o, const Anope::string &n) : SSLService(o, n)
00199 {
00200 }
00201
00202 void MySSLService::Init(Socket *s)
00203 {
00204 if (s->io != &NormalSocketIO)
00205 throw CoreException("Socket initializing SSL twice");
00206
00207 s->io = new SSLSocketIO();
00208 }
00209
00210 SSLSocketIO::SSLSocketIO()
00211 {
00212 this->sslsock = NULL;
00213 }
00214
00215 int SSLSocketIO::Recv(Socket *s, char *buf, size_t sz)
00216 {
00217 int i = SSL_read(this->sslsock, buf, sz);
00218 TotalRead += i;
00219 return i;
00220 }
00221
00222 int SSLSocketIO::Send(Socket *s, const char *buf, size_t sz)
00223 {
00224 int i = SSL_write(this->sslsock, buf, sz);
00225 TotalWritten += i;
00226 return i;
00227 }
00228
00229 ClientSocket *SSLSocketIO::Accept(ListenSocket *s)
00230 {
00231 if (s->io == &NormalSocketIO)
00232 throw SocketException("Attempting to accept on uninitialized socket with SSL");
00233
00234 sockaddrs conaddr;
00235
00236 socklen_t size = sizeof(conaddr);
00237 int newsock = accept(s->GetFD(), &conaddr.sa, &size);
00238
00239 #ifndef INVALID_SOCKET
00240 const int INVALID_SOCKET = -1;
00241 #endif
00242
00243 if (newsock < 0 || newsock == INVALID_SOCKET)
00244 throw SocketException("Unable to accept connection: " + Anope::LastError());
00245
00246 ClientSocket *newsocket = s->OnAccept(newsock, conaddr);
00247 me->service.Init(newsocket);
00248 SSLSocketIO *io = anope_dynamic_static_cast<SSLSocketIO *>(newsocket->io);
00249
00250 io->sslsock = SSL_new(server_ctx);
00251 if (!io->sslsock)
00252 throw SocketException("Unable to initialize SSL socket");
00253
00254 SSL_set_accept_state(io->sslsock);
00255
00256 if (!SSL_set_fd(io->sslsock, newsocket->GetFD()))
00257 throw SocketException("Unable to set SSL fd");
00258
00259 newsocket->flags[SF_ACCEPTING] = true;
00260 this->FinishAccept(newsocket);
00261
00262 return newsocket;
00263 }
00264
00265 SocketFlag SSLSocketIO::FinishAccept(ClientSocket *cs)
00266 {
00267 if (cs->io == &NormalSocketIO)
00268 throw SocketException("Attempting to finish connect uninitialized socket with SSL");
00269 else if (cs->flags[SF_ACCEPTED])
00270 return SF_ACCEPTED;
00271 else if (!cs->flags[SF_ACCEPTING])
00272 throw SocketException("SSLSocketIO::FinishAccept called for a socket not accepted nor accepting?");
00273
00274 SSLSocketIO *io = anope_dynamic_static_cast<SSLSocketIO *>(cs->io);
00275
00276 int ret = SSL_accept(io->sslsock);
00277 if (ret <= 0)
00278 {
00279 int error = SSL_get_error(io->sslsock, ret);
00280 if (ret == -1 && (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE))
00281 {
00282 SocketEngine::Change(cs, error == SSL_ERROR_WANT_WRITE, SF_WRITABLE);
00283 SocketEngine::Change(cs, error == SSL_ERROR_WANT_READ, SF_READABLE);
00284 return SF_ACCEPTING;
00285 }
00286 else
00287 {
00288 cs->OnError(ERR_error_string(ERR_get_error(), NULL));
00289 cs->flags[SF_DEAD] = true;
00290 cs->flags[SF_ACCEPTING] = false;
00291 return SF_DEAD;
00292 }
00293 }
00294 else
00295 {
00296 cs->flags[SF_ACCEPTED] = true;
00297 cs->flags[SF_ACCEPTING] = false;
00298 SocketEngine::Change(cs, false, SF_WRITABLE);
00299 SocketEngine::Change(cs, true, SF_READABLE);
00300 cs->OnAccept();
00301 return SF_ACCEPTED;
00302 }
00303 }
00304
00305 void SSLSocketIO::Connect(ConnectionSocket *s, const Anope::string &target, int port)
00306 {
00307 if (s->io == &NormalSocketIO)
00308 throw SocketException("Attempting to connect uninitialized socket with SSL");
00309
00310 s->flags[SF_CONNECTING] = s->flags[SF_CONNECTED] = false;
00311
00312 s->conaddr.pton(s->IsIPv6() ? AF_INET6 : AF_INET, target, port);
00313 int c = connect(s->GetFD(), &s->conaddr.sa, s->conaddr.size());
00314 if (c == -1)
00315 {
00316 if (Anope::LastErrorCode() != EINPROGRESS)
00317 {
00318 s->OnError(Anope::LastError());
00319 s->flags[SF_DEAD] = true;
00320 return;
00321 }
00322 else
00323 {
00324 SocketEngine::Change(s, true, SF_WRITABLE);
00325 s->flags[SF_CONNECTING] = true;
00326 return;
00327 }
00328 }
00329 else
00330 {
00331 s->flags[SF_CONNECTING] = true;
00332 this->FinishConnect(s);
00333 }
00334 }
00335
00336 SocketFlag SSLSocketIO::FinishConnect(ConnectionSocket *s)
00337 {
00338 if (s->io == &NormalSocketIO)
00339 throw SocketException("Attempting to finish connect uninitialized socket with SSL");
00340 else if (s->flags[SF_CONNECTED])
00341 return SF_CONNECTED;
00342 else if (!s->flags[SF_CONNECTING])
00343 throw SocketException("SSLSocketIO::FinishConnect called for a socket not connected nor connecting?");
00344
00345 SSLSocketIO *io = anope_dynamic_static_cast<SSLSocketIO *>(s->io);
00346
00347 if (io->sslsock == NULL)
00348 {
00349 io->sslsock = SSL_new(client_ctx);
00350 if (!io->sslsock)
00351 throw SocketException("Unable to initialize SSL socket");
00352
00353 if (!SSL_set_fd(io->sslsock, s->GetFD()))
00354 throw SocketException("Unable to set SSL fd");
00355 }
00356
00357 int ret = SSL_connect(io->sslsock);
00358 if (ret <= 0)
00359 {
00360 int error = SSL_get_error(io->sslsock, ret);
00361 if (ret == -1 && (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE))
00362 {
00363 SocketEngine::Change(s, error == SSL_ERROR_WANT_WRITE, SF_WRITABLE);
00364 SocketEngine::Change(s, error == SSL_ERROR_WANT_READ, SF_READABLE);
00365 return SF_CONNECTING;
00366 }
00367 else
00368 {
00369 s->OnError(ERR_error_string(ERR_get_error(), NULL));
00370 s->flags[SF_CONNECTING] = false;
00371 s->flags[SF_DEAD] = true;
00372 return SF_DEAD;
00373 }
00374 }
00375 else
00376 {
00377 s->flags[SF_CONNECTING] = false;
00378 s->flags[SF_CONNECTED] = true;
00379 SocketEngine::Change(s, false, SF_WRITABLE);
00380 SocketEngine::Change(s, true, SF_READABLE);
00381 s->OnConnect();
00382 return SF_CONNECTED;
00383 }
00384 }
00385
00386 void SSLSocketIO::Destroy()
00387 {
00388 if (this->sslsock)
00389 {
00390 SSL_shutdown(this->sslsock);
00391 SSL_free(this->sslsock);
00392 }
00393
00394 delete this;
00395 }
00396
00397 MODULE_INIT(SSLModule)