From 7d5b81e9936b1c778fd6408f3f22478e9ab9486b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 6 Sep 2008 03:15:06 +0200 Subject: X.509-basierte TLS-Verbindung funktioniert --- src/Common/Request/Request.h | 2 +- src/Core/ConfigManager.cpp | 16 ++++++++++++---- src/Core/ConfigManager.h | 9 ++++++++- src/Core/ConnectionManager.cpp | 9 ++++++--- src/Core/ConnectionManager.h | 4 +++- src/Net/ClientConnection.cpp | 8 +------- src/Net/ClientConnection.h | 18 +++++------------- src/Net/Connection.cpp | 4 ++++ src/Net/Connection.h | 5 +++++ src/Net/Listener.cpp | 6 +++--- src/Net/Listener.h | 4 +++- src/Net/ServerConnection.cpp | 18 +++++------------- src/Net/ServerConnection.h | 20 ++++++++------------ src/mad-core.conf | 6 ++++++ src/mad-core.cpp | 2 +- src/madc.cpp | 2 ++ 16 files changed, 73 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/Common/Request/Request.h b/src/Common/Request/Request.h index e156b1b..5c8d6c4 100644 --- a/src/Common/Request/Request.h +++ b/src/Common/Request/Request.h @@ -1,7 +1,7 @@ /* * Request.h * - * Copyright (C) 2008 Matthias Schiffer + * Copyright (C) 2008 Matthias Schiffer * * 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 diff --git a/src/Core/ConfigManager.cpp b/src/Core/ConfigManager.cpp index b4c81bc..5f40afd 100644 --- a/src/Core/ConfigManager.cpp +++ b/src/Core/ConfigManager.cpp @@ -42,6 +42,18 @@ bool ConfigManager::parseLine(const std::vector §ion, const std // TODO Logging } } + else if(Common::Util::tolower(key) == "x509trustfile") { + x509TrustFile = value; + } + else if(Common::Util::tolower(key) == "x509crlfile") { + x509CrlFile = value; + } + else if(Common::Util::tolower(key) == "x509certfile") { + x509CertFile = value; + } + else if(Common::Util::tolower(key) == "x509keyfile") { + x509KeyFile = value; + } else { // TODO Logging @@ -71,9 +83,5 @@ ConfigManager::ConfigManager() { loadFile("mad-core.conf"); } -ConfigManager::~ConfigManager() { - // TODO Auto-generated destructor stub -} - } } diff --git a/src/Core/ConfigManager.h b/src/Core/ConfigManager.h index 6a5cf2c..3b23750 100644 --- a/src/Core/ConfigManager.h +++ b/src/Core/ConfigManager.h @@ -24,6 +24,7 @@ #include #include #include +#include namespace Mad { namespace Core { @@ -39,15 +40,21 @@ class ConfigManager : public Common::ConfigManager { std::vector listeners; std::vector daemons; + std::string x509TrustFile, x509CrlFile, x509CertFile, x509KeyFile; + protected: virtual bool parseLine(const std::vector §ion, const std::string &key, const std::string &value); public: ConfigManager(); - virtual ~ConfigManager(); const std::vector& getListenerAddresses() const {return listeners;} const std::vector& getDaemonList() const {return daemons;} + + const std::string& getX509TrustFile() const {return x509TrustFile;} + const std::string& getX509CrlFile() const {return x509CrlFile;} + const std::string& getX509CertFile() const {return x509CertFile;} + const std::string& getX509KeyFile() const {return x509KeyFile;} }; } diff --git a/src/Core/ConnectionManager.cpp b/src/Core/ConnectionManager.cpp index b1cfd40..a537539 100644 --- a/src/Core/ConnectionManager.cpp +++ b/src/Core/ConnectionManager.cpp @@ -18,6 +18,7 @@ */ #include "ConnectionManager.h" +#include "ConfigManager.h" #include "RequestHandler/CertificateRequestHandler.h" #include #include @@ -51,12 +52,14 @@ void ConnectionManager::refreshPollfds() { } } -ConnectionManager::ConnectionManager(const std::vector &listenerAddresses) : requestManager(true) { +ConnectionManager::ConnectionManager(const ConfigManager& configManager) : requestManager(true) { requestManager.registerPacketType(Net::Packet::TYPE_CERT_REQ); + const std::vector &listenerAddresses = configManager.getListenerAddresses(); + if(listenerAddresses.empty()) { try { - listeners.push_back(new Net::Listener()); + listeners.push_back(new Net::Listener(configManager.getX509CertFile(), configManager.getX509KeyFile())); } catch(Net::Exception &e) { // TODO: Log error @@ -65,7 +68,7 @@ ConnectionManager::ConnectionManager(const std::vector &listener else { for(std::vector::const_iterator address = listenerAddresses.begin(); address != listenerAddresses.end(); ++address) { try { - listeners.push_back(new Net::Listener(*address)); + listeners.push_back(new Net::Listener(configManager.getX509CertFile(), configManager.getX509KeyFile(), *address)); } catch(Net::Exception &e) { // TODO: Log error diff --git a/src/Core/ConnectionManager.h b/src/Core/ConnectionManager.h index 54d5d5e..7429a44 100644 --- a/src/Core/ConnectionManager.h +++ b/src/Core/ConnectionManager.h @@ -37,6 +37,8 @@ class Packet; namespace Core { +class ConfigManager; + class ConnectionManager { private: // Prevent shallow copy @@ -56,7 +58,7 @@ class ConnectionManager { void refreshPollfds(); public: - ConnectionManager(const std::vector &listenerAddresses); + ConnectionManager(const ConfigManager& configManager); virtual ~ConnectionManager(); bool wait(int timeout) { diff --git a/src/Net/ClientConnection.cpp b/src/Net/ClientConnection.cpp index 8705795..e0058ff 100644 --- a/src/Net/ClientConnection.cpp +++ b/src/Net/ClientConnection.cpp @@ -87,14 +87,8 @@ void ClientConnection::connect(const IPAddress &address, bool daemon0) throw(Con setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)); gnutls_init(&session, GNUTLS_CLIENT); - gnutls_set_default_priority(session); - - const int kx_list[] = {GNUTLS_KX_ANON_DH, 0}; - gnutls_kx_set_priority(session, kx_list); - - gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); - + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_ptr(session, reinterpret_cast(sock)); handshake(); diff --git a/src/Net/ClientConnection.h b/src/Net/ClientConnection.h index 18b1a02..280f382 100644 --- a/src/Net/ClientConnection.h +++ b/src/Net/ClientConnection.h @@ -30,24 +30,16 @@ class IPAddress; class ClientConnection : public Connection { private: - gnutls_anon_client_credentials_t anoncred; - bool daemon; - + void connectionHeaderReceiveHandler(const void *data, unsigned long length); - + protected: virtual void connectionHeader(); - + public: - ClientConnection() : daemon(0) { - gnutls_anon_allocate_client_credentials(&anoncred); - } - - virtual ~ClientConnection() { - gnutls_anon_free_client_credentials(anoncred); - } - + ClientConnection() : daemon(0) {} + void connect(const IPAddress &address, bool daemon0 = false) throw(ConnectionException); }; diff --git a/src/Net/Connection.cpp b/src/Net/Connection.cpp index 5d221fb..ac3121d 100644 --- a/src/Net/Connection.cpp +++ b/src/Net/Connection.cpp @@ -22,6 +22,8 @@ #include #include +#include + namespace Mad { namespace Net { @@ -34,6 +36,8 @@ void Connection::doHandshake() { if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) return; + std::cerr << "Handshake error: " << gnutls_strerror(ret) << std::endl; + // TODO: Error doDisconnect(); return; diff --git a/src/Net/Connection.h b/src/Net/Connection.h index 0949ec4..21e8444 100644 --- a/src/Net/Connection.h +++ b/src/Net/Connection.h @@ -98,6 +98,7 @@ class Connection { int sock; gnutls_session_t session; + gnutls_certificate_credentials_t x509_cred; IPAddress *peer; @@ -128,6 +129,8 @@ class Connection { Connection() : state(DISCONNECTED), peer(0) { transR.length = transR.transmitted = 0; transR.data = 0; + + gnutls_certificate_allocate_credentials(&x509_cred); } virtual ~Connection() { @@ -141,6 +144,8 @@ class Connection { delete [] transS.front().data; transS.pop(); } + + gnutls_certificate_free_credentials(x509_cred); } bool isConnected() const {return (state != DISCONNECTED);} diff --git a/src/Net/Listener.cpp b/src/Net/Listener.cpp index 3b2e3d6..892d057 100644 --- a/src/Net/Listener.cpp +++ b/src/Net/Listener.cpp @@ -28,8 +28,8 @@ namespace Mad { namespace Net { -Listener::Listener(const IPAddress &address0) throw(ConnectionException) -: address(address0) { +Listener::Listener(const std::string &x905CertFile0, const std::string &x905KeyFile0, const IPAddress &address0) throw(ConnectionException) +: x905CertFile(x905CertFile0), x905KeyFile(x905KeyFile0), address(address0) { gnutls_dh_params_init(&dh_params); gnutls_dh_params_generate2(dh_params, 768); @@ -99,7 +99,7 @@ ServerConnection* Listener::getConnection(const std::map &poll while((sd = accept(sock, reinterpret_cast(&sa), &addrlen)) >= 0) { - connections.push_back(new ServerConnection(sd, IPAddress(sa), dh_params)); + connections.push_back(new ServerConnection(sd, IPAddress(sa), dh_params, x905CertFile, x905KeyFile)); addrlen = sizeof(sa); } diff --git a/src/Net/Listener.h b/src/Net/Listener.h index 81260ed..63e12c6 100644 --- a/src/Net/Listener.h +++ b/src/Net/Listener.h @@ -27,6 +27,7 @@ #include #include #include +#include namespace Mad { namespace Net { @@ -35,6 +36,7 @@ class ServerConnection; class Listener { private: + std::string x905CertFile, x905KeyFile; IPAddress address; int sock; @@ -47,7 +49,7 @@ class Listener { Listener& operator=(const Listener &o); public: - Listener(const IPAddress &address0 = IPAddress()) throw(ConnectionException); + Listener(const std::string &x905CertFile0, const std::string &x905KeyFile0, const IPAddress &address0 = IPAddress()) throw(ConnectionException); virtual ~Listener(); std::vector getPollfds() const; diff --git a/src/Net/ServerConnection.cpp b/src/Net/ServerConnection.cpp index c011f66..0c35991 100644 --- a/src/Net/ServerConnection.cpp +++ b/src/Net/ServerConnection.cpp @@ -57,26 +57,18 @@ void ServerConnection::connectionHeaderReceiveHandler(const void *data, unsigned enterReceiveLoop(); } -ServerConnection::ServerConnection(int sock0, const IPAddress &address, gnutls_dh_params_t dh_params) +ServerConnection::ServerConnection(int sock0, const IPAddress &address, gnutls_dh_params_t dh_params, const std::string &x905CertFile, const std::string &x905KeyFile) : daemon(false) { sock = sock0; - gnutls_anon_allocate_server_credentials(&anoncred); - - - gnutls_anon_set_server_dh_params(anoncred, dh_params); - peer = new IPAddress(address); - gnutls_init(&session, GNUTLS_SERVER); + gnutls_certificate_set_dh_params(x509_cred, dh_params); + gnutls_certificate_set_x509_key_file(x509_cred, x905CertFile.c_str(), x905KeyFile.c_str(), GNUTLS_X509_FMT_PEM); + gnutls_init(&session, GNUTLS_SERVER); gnutls_set_default_priority(session); - - const int kx_list[] = {GNUTLS_KX_ANON_DH, 0}; - gnutls_kx_set_priority(session, kx_list); - - gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); - + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_ptr(session, reinterpret_cast(sock)); handshake(); diff --git a/src/Net/ServerConnection.h b/src/Net/ServerConnection.h index ff88ad3..9a4d86b 100644 --- a/src/Net/ServerConnection.h +++ b/src/Net/ServerConnection.h @@ -31,28 +31,24 @@ class Listener; class ServerConnection : public Connection { friend class Listener; - + private: IPAddress *peer; - + bool daemon; - + gnutls_anon_server_credentials_t anoncred; - + void connectionHeaderReceiveHandler(const void *data, unsigned long length); - + protected: - ServerConnection(int sock0, const IPAddress &address, gnutls_dh_params_t dh_params); - + ServerConnection(int sock0, const IPAddress &address, gnutls_dh_params_t dh_params, const std::string &x905certFile, const std::string &x905keyFile); + virtual void connectionHeader() { rawReceive(sizeof(ConnectionHeader), sigc::mem_fun(this, &ServerConnection::connectionHeaderReceiveHandler)); } - + public: - virtual ~ServerConnection() { - gnutls_anon_free_server_credentials(anoncred); - } - bool isDaemonConnection() const {return daemon;} }; diff --git a/src/mad-core.conf b/src/mad-core.conf index 9a03e00..9eda7c3 100644 --- a/src/mad-core.conf +++ b/src/mad-core.conf @@ -2,6 +2,12 @@ ConfigMethod Mysql Listen * + +X509TrustFile ../Cert/ca-cert.pem +#X509CrlFile ../Cert/crl.pem +X509CertFile ../Cert/cert.pem +X509KeyFile ../Cert/key.pem + Daemon ic01 { IpAddress 192.168.2.11 } diff --git a/src/mad-core.cpp b/src/mad-core.cpp index d78ec3e..0bbee97 100644 --- a/src/mad-core.cpp +++ b/src/mad-core.cpp @@ -33,7 +33,7 @@ int main() { Mad::Net::Connection::init(); - Mad::Core::ConnectionManager *connectionManager = new Mad::Core::ConnectionManager(configManager.getListenerAddresses()); + Mad::Core::ConnectionManager *connectionManager = new Mad::Core::ConnectionManager(configManager); while(true) { if(connectionManager->wait(10000)) diff --git a/src/madc.cpp b/src/madc.cpp index e4a36a4..f08be77 100644 --- a/src/madc.cpp +++ b/src/madc.cpp @@ -23,6 +23,7 @@ #include "Common/RequestManager.h" #include "Common/Request/CertificateRequest.h" #include "Common/Request/DisconnectRequest.h" +#include "Common/Request/IdentifyRequest.h" #include int main() { @@ -43,6 +44,7 @@ int main() { requestManager.registerConnection(connection); + Mad::Common::Request::IdentifyRequest::send(connection, requestManager, "localhost"); Mad::Common::Request::CertificateRequest::send(connection, requestManager, "host"); Mad::Common::Request::DisconnectRequest::send(connection, requestManager); -- cgit v1.2.3