From 99ec36989631dd116524a5fab03f1c1977870752 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 11 Jun 2008 23:11:25 +0200 Subject: Einfache TLS-Client-Verbindung implementiert --- src/Net/ClientConnection.cpp | 82 +++++++++++++++++++++++++++++++++++++++ src/Net/ClientConnection.h | 57 +++++++++++++++++++++++++++ src/Net/Connection.cpp | 34 ---------------- src/Net/Connection.h | 20 ++++++++-- src/Net/ConnectionException.h | 42 ++++++++++++++++++++ src/Net/Exception.h | 36 +++++++++++++++++ src/Net/IPAddress.h | 54 ++++++++++++++++++++++++++ src/Net/InvalidAddressException.h | 41 ++++++++++++++++++++ src/Net/Makefile.am | 5 ++- src/Net/Makefile.in | 19 ++++++--- 10 files changed, 347 insertions(+), 43 deletions(-) create mode 100644 src/Net/ClientConnection.cpp create mode 100644 src/Net/ClientConnection.h delete mode 100644 src/Net/Connection.cpp create mode 100644 src/Net/ConnectionException.h create mode 100644 src/Net/Exception.h create mode 100644 src/Net/IPAddress.h create mode 100644 src/Net/InvalidAddressException.h (limited to 'src/Net') diff --git a/src/Net/ClientConnection.cpp b/src/Net/ClientConnection.cpp new file mode 100644 index 0000000..396c70a --- /dev/null +++ b/src/Net/ClientConnection.cpp @@ -0,0 +1,82 @@ +/* + * ClientConnection.cpp + * + * 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 + * 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 . + */ + +#include "ClientConnection.h" +#include "IPAddress.h" +#include +#include +#include + +namespace Mad { +namespace Net { + +void ClientConnection::connect(const IPAddress &address) throw(ConnectionException) { + const int kx_list[] = {GNUTLS_KX_ANON_DH, 0}; + + if(connected) + disconnect(); + + peer = new IPAddress(address); + + sock = socket(PF_INET, SOCK_STREAM, 0); + if(sock < 0) + throw ConnectionException("socket()", std::strerror(errno)); + + if(::connect(sock, peer->getSockAddr(), peer->getSockAddrLength()) < 0) + throw ConnectionException("connect()", std::strerror(errno)); + + gnutls_anon_allocate_client_credentials(&anoncred); + gnutls_init(&session, GNUTLS_CLIENT); + + gnutls_set_default_priority(session); + gnutls_kx_set_priority(session, kx_list); + + gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); + + gnutls_transport_set_ptr(session, reinterpret_cast(sock)); + + int ret = gnutls_handshake(session); + if(ret < 0) + throw ConnectionException("gnutls_handshake()", gnutls_strerror(ret)); + + connected = true; +} + +void ClientConnection::disconnect() { + gnutls_bye(session, GNUTLS_SHUT_RDWR); + + if(sock >= 0) { + shutdown(sock, SHUT_RDWR); /* no more receptions */ + close(sock); + sock = -1; + } + + gnutls_deinit(session); + gnutls_anon_free_client_credentials(anoncred); + + if(peer) { + delete peer; + peer = 0; + } + + connected = false; +} + +} +} diff --git a/src/Net/ClientConnection.h b/src/Net/ClientConnection.h new file mode 100644 index 0000000..684dbfc --- /dev/null +++ b/src/Net/ClientConnection.h @@ -0,0 +1,57 @@ +/* + * ClientConnection.h + * + * 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 + * 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 . + */ + +#ifndef MAD_NET_CLIENTCONNECTION_H_ +#define MAD_NET_CLIENTCONNECTION_H_ + +#include "Connection.h" +#include "ConnectionException.h" + +namespace Mad { +namespace Net { + +class IPAddress; + +class ClientConnection : public Connection { + private: + bool connected; + IPAddress *peer; + + int sock; + gnutls_session_t session; + gnutls_anon_client_credentials_t anoncred; + + public: + ClientConnection() : connected(false), peer(0), sock(-1), session(0) {} + virtual ~ClientConnection() { + if(connected) + disconnect(); + } + + void connect(const IPAddress &address) throw(ConnectionException); + void disconnect(); + + virtual bool isConnected() const {return connected;} + virtual const IPAddress* getPeer() const {return peer;} +}; + +} +} + +#endif /*MAD_NET_CLIENTCONNECTION_H_*/ diff --git a/src/Net/Connection.cpp b/src/Net/Connection.cpp deleted file mode 100644 index 1c2cc62..0000000 --- a/src/Net/Connection.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Connection.cpp - * - * 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 - * 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 . - */ - -#include "Connection.h" - -namespace Mad { -namespace Net { - -Connection::Connection() { - -} - -Connection::~Connection() { - -} - -} -} diff --git a/src/Net/Connection.h b/src/Net/Connection.h index a40407c..c8b45c6 100644 --- a/src/Net/Connection.h +++ b/src/Net/Connection.h @@ -20,16 +20,30 @@ #ifndef MAD_NET_CONNECTION_H_ #define MAD_NET_CONNECTION_H_ +#include + namespace Mad { namespace Net { +class IPAddress; + class Connection { public: - Connection(); - virtual ~Connection(); + virtual ~Connection() {} + + virtual bool isConnected() const = 0; + virtual const IPAddress* getPeer() const = 0; + + static void init() { + gnutls_global_init(); + } + + static void deinit() { + gnutls_global_deinit(); + } }; } } -#endif /*CONNECTION_H_*/ +#endif /*MAD_NET_CONNECTION_H_*/ diff --git a/src/Net/ConnectionException.h b/src/Net/ConnectionException.h new file mode 100644 index 0000000..cb9e10e --- /dev/null +++ b/src/Net/ConnectionException.h @@ -0,0 +1,42 @@ +/* + * ConnectionException.h + * + * 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 + * 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 . + */ + +#ifndef MAD_NET_CONNECTIONEXCEPTION_H_ +#define MAD_NET_CONNECTIONEXCEPTION_H_ + +#include "Exception.h" + +namespace Mad { +namespace Net { + +class ConnectionException : public Exception { + private: + std::string str; + + public: + ConnectionException(const std::string &during, const std::string &error) + : str(during + ": " + error) {} + + virtual std::string& what() {return str;} +}; + +} +} + +#endif /*MAD_NET_CONNECTIONEXCEPTION_H_*/ diff --git a/src/Net/Exception.h b/src/Net/Exception.h new file mode 100644 index 0000000..10a9167 --- /dev/null +++ b/src/Net/Exception.h @@ -0,0 +1,36 @@ +/* + * Exception.h + * + * 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 + * 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 . + */ + +#ifndef MAD_NET_EXCEPTION_H_ +#define MAD_NET_EXCEPTION_H_ + +#include + +namespace Mad { +namespace Net { + +class Exception { + public: + virtual std::string& what() = 0; +}; + +} +} + +#endif /*MAD_NET_EXCEPTION_H_*/ diff --git a/src/Net/IPAddress.h b/src/Net/IPAddress.h new file mode 100644 index 0000000..e892323 --- /dev/null +++ b/src/Net/IPAddress.h @@ -0,0 +1,54 @@ +/* + * IPAddress.h + * + * 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 + * 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 . + */ + +#ifndef MAD_NET_IPADDRESS_H_ +#define MAD_NET_IPADDRESS_H_ + +#include +#include +#include "InvalidAddressException.h" + +namespace Mad { +namespace Net { + +class IPAddress { + private: + std::string addr; + unsigned short p; + struct sockaddr_in sa; + + public: + IPAddress(const std::string &address, unsigned short port) throw(InvalidAddressException) : addr(address), p(port) { + sa.sin_family = AF_INET; + sa.sin_port = htons(port); + if(!inet_pton(AF_INET, address.c_str(), &sa.sin_addr)) + throw InvalidAddressException(address); + } + + const std::string& getAddress() const {return addr;} + unsigned short getPort() const {return p;} + + struct sockaddr* getSockAddr() {return reinterpret_cast(&sa);} + socklen_t getSockAddrLength() const {return sizeof(sa);} +}; + +} +} + +#endif /*MAD_NET_IPADDRESS_H_*/ diff --git a/src/Net/InvalidAddressException.h b/src/Net/InvalidAddressException.h new file mode 100644 index 0000000..a547106 --- /dev/null +++ b/src/Net/InvalidAddressException.h @@ -0,0 +1,41 @@ +/* + * InvalidAddressException.h + * + * 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 + * 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 . + */ + +#ifndef MAD_NET_INVALIDADDRESSEXCEPTION_H_ +#define MAD_NET_INVALIDADDRESSEXCEPTION_H_ + +#include "Exception.h" + +namespace Mad { +namespace Net { + +class InvalidAddressException : public Exception { + private: + std::string str; + + public: + InvalidAddressException(const std::string &addr) : str("Invalid address: " + addr) {} + + virtual std::string& what() {return str;} +}; + +} +} + +#endif /*MAD_NET_INVALIDADDRESSEXCEPTION_H_*/ diff --git a/src/Net/Makefile.am b/src/Net/Makefile.am index 18d86ea..0fe1c42 100644 --- a/src/Net/Makefile.am +++ b/src/Net/Makefile.am @@ -1,3 +1,6 @@ noinst_LTLIBRARIES = libnet.la -libnet_la_SOURCES = Connection.cpp +libnet_la_SOURCES = ClientConnection.cpp + +noinst_HEADERS = ClientConnection.h Connection.h Exception.h ConnectionException.h \ + InvalidAddressException.h IPAddress.h diff --git a/src/Net/Makefile.in b/src/Net/Makefile.in index 130539a..3281bc4 100644 --- a/src/Net/Makefile.in +++ b/src/Net/Makefile.in @@ -14,6 +14,7 @@ @SET_MAKE@ + VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -33,7 +34,8 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/Net -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ @@ -43,7 +45,7 @@ CONFIG_HEADER = $(top_builddir)/src/config.h CONFIG_CLEAN_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libnet_la_LIBADD = -am_libnet_la_OBJECTS = Connection.lo +am_libnet_la_OBJECTS = ClientConnection.lo libnet_la_OBJECTS = $(am_libnet_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp @@ -59,6 +61,7 @@ CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libnet_la_SOURCES) DIST_SOURCES = $(libnet_la_SOURCES) +HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -91,6 +94,8 @@ EXEEXT = @EXEEXT@ F77 = @F77@ FFLAGS = @FFLAGS@ GREP = @GREP@ +GnuTLS_CFLAGS = @GnuTLS_CFLAGS@ +GnuTLS_LIBS = @GnuTLS_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -114,6 +119,7 @@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ @@ -172,7 +178,10 @@ target_alias = @target_alias@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libnet.la -libnet_la_SOURCES = Connection.cpp +libnet_la_SOURCES = ClientConnection.cpp +noinst_HEADERS = ClientConnection.h Connection.h Exception.h ConnectionException.h \ + InvalidAddressException.h IPAddress.h + all: all-am .SUFFIXES: @@ -224,7 +233,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClientConnection.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -328,7 +337,7 @@ distdir: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(LTLIBRARIES) +all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: install: install-am install-exec: install-exec-am -- cgit v1.2.3