From b795877967e0d0951b810673c0228dfa7d8d867e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Guti=C3=A9rrez=20de=20Quevedo=20P=C3=A9?= =?UTF-8?q?rez?= Date: Tue, 25 Mar 2025 10:59:11 +0100 Subject: [PATCH] Rearrange stuff --- CMakeLists.txt | 1 + dists/fc_init | 62 ----- dists/hermes.spec.in | 77 ------ include/Configfile.h | 144 +++++++++++ {src => include}/Database.h | 0 {src => include}/Exception.h | 0 {src => include}/FileLogger.h | 0 {src => include}/Logger.h | 0 {src => include}/NullLogger.h | 0 {src => include}/Proxy.h | 5 + {src => include}/ServerSocket.h | 0 {src => include}/Socket.h | 0 {src => include}/SocketInterface.h | 0 {src => include}/Spf.h | 0 {src => include}/UnixLogger.h | 0 {src => include}/Utils.h | 0 {src => include}/hermes.h | 0 src/Configfile.cpp | 314 ++++++++++++++++++++++++ test/CMakeLists.txt | 14 ++ {src/test => test}/mocks/libspf2_mock.h | 0 {src/test => test}/mocks/socket_mock.h | 0 {src/test => test}/tests/proxy_test.cpp | 0 {src/test => test}/tests/spf_test.cpp | 0 23 files changed, 478 insertions(+), 139 deletions(-) delete mode 100755 dists/fc_init delete mode 100644 dists/hermes.spec.in create mode 100644 include/Configfile.h rename {src => include}/Database.h (100%) rename {src => include}/Exception.h (100%) rename {src => include}/FileLogger.h (100%) rename {src => include}/Logger.h (100%) rename {src => include}/NullLogger.h (100%) rename {src => include}/Proxy.h (63%) rename {src => include}/ServerSocket.h (100%) rename {src => include}/Socket.h (100%) rename {src => include}/SocketInterface.h (100%) rename {src => include}/Spf.h (100%) rename {src => include}/UnixLogger.h (100%) rename {src => include}/Utils.h (100%) rename {src => include}/hermes.h (100%) create mode 100644 src/Configfile.cpp create mode 100644 test/CMakeLists.txt rename {src/test => test}/mocks/libspf2_mock.h (100%) rename {src/test => test}/mocks/socket_mock.h (100%) rename {src/test => test}/tests/proxy_test.cpp (100%) rename {src/test => test}/tests/spf_test.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index e25dd14..652d7fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ if(WIN32) target_compile_definitions(hermes PRIVATE WIN32) endif() +target_include_directories(hermes PRIVATE include) target_compile_definitions(hermes PRIVATE LOGGER_CLASS=${LOGGER_CLASS}) target_sources(hermes PRIVATE src/${LOGGER_CLASS}.cpp) diff --git a/dists/fc_init b/dists/fc_init deleted file mode 100755 index f4f30a4..0000000 --- a/dists/fc_init +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -# Startup script for hermes -# -# chkconfig: 3 95 05 -# description: hermes - -# Source function library. -. /etc/rc.d/init.d/functions - -prog=hermes -configfile=/etc/hermes/hermesrc - -start() { - echo -n $"Starting $prog: " - daemon --check=$prog /usr/bin/hermes $configfile - RETVAL=$? - echo -} - -stop() { - echo -n $"Stopping $prog: " - killproc $prog - RETVAL=$? - echo -} - -safestop() { - echo -n $"Stopping $prog(will process pending connections):" - killproc $prog -INT - rm /var/run/$prog.pid - RETVAL=$? - echo -} - -case "$1" in - start) - start - ;; - - stop) - stop - ;; - - restart) - safestop - sleep 2 - start - ;; - condrestart) - if test "x`pidfileofproc $prog`" != x; then - stop - start - fi - ;; - - *) - echo $"Usage: $0 {start|stop|restart|condrestart}" - exit 1 - -esac - -exit $RETVAL diff --git a/dists/hermes.spec.in b/dists/hermes.spec.in deleted file mode 100644 index c69296c..0000000 --- a/dists/hermes.spec.in +++ /dev/null @@ -1,77 +0,0 @@ -Summary: An anti-spam SMTP proxy -Name: @PACKAGE@ -Version: @VERSION@ -Release: 0 -License: GPL -Group: System Environment/Daemons -Packager: Veit Wahlich -URL: http://www.hermes-project.com/ -Source0: http://www.hermes-project.com/files/%{name}-%{version}.tar.bz2 -Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root - -%description -hermes is a generic, lightweight, portable and fast anti-spam smtp proxy. -Supports greylisting, dns blacklisting/whitelisting, protocol throttling, banner delaying, spf and some -other tricks to reject most spam before it even enters your system. - -%prep -%setup -q - -%build -%configure --docdir=%{_datadir}/doc/%{name}-%{version} -%__make %{?_smp_mflags} - -%install -%__rm -rf %{buildroot} -%__make DESTDIR=%{buildroot} install -%__mkdir_p %{buildroot}%{_sysconfdir}/rc.d/init.d -%__mkdir_p %{buildroot}%{_sysconfdir}/hermes -%__mkdir_p %{buildroot}%{_localstatedir}/hermes -%__install -m 0755 dists/fc_init %{buildroot}%{_sysconfdir}/rc.d/init.d/hermes -%__install -m 0600 dists/hermesrc.example %{buildroot}%{_sysconfdir}/hermes/hermesrc - -%clean -%__rm -rf %{buildroot} - -%post -/sbin/chkconfig --add hermes - -%preun -if [ $1 = 0 ]; then # execute this only if we are NOT doing an upgrade - %{_sysconfdir}/rc.d/init.d/hermes stop >/dev/null 2>&1 - /sbin/chkconfig --del hermes -fi -exit 0 - -%files -%defattr(-, root, root, 0755) -%doc ChangeLog TODO AUTHORS dists/hermesrc.example docs/hermes-options.html docs/installing-hermes.txt docs/gpl.txt -%{_bindir}/hermes -%{_sysconfdir}/rc.d/init.d/hermes -%config %{_sysconfdir}/hermes/hermesrc -%dir %attr(0700,nobody,nobody) %{_localstatedir}/hermes - -%changelog -* Thu Jun 14 2007 Juan José Gutiérrez de Quevedo 1.4 -- removed patches, they are now on upstream - -* Fri May 25 2007 Veit Wahlich 1.3-2 -- added patch fix_whether (documentation fixes) -- added patch add_rejectnoresolve (reject on no DNS reverse resolution feature) -- changed RPM group to system daemon standard - -* Sat May 19 2007 Veit Wahlich 1.3-1 -- Made /etc/hermes/hermesrc readonly as it may contain passwords -- Fixed ownership and permissions of /var/hermes to match configuration default -- Silenced setup macro output as required by some distributions -- Fixed docdir to a LSB compliant location, will be replaced by rpmbuild -- Packaged extra documentation -- Removed hermes-options.html.in from docs -- Use directory macros for files section -- Further specfile cleanups and macro usage - -* Tue May 15 2007 Juan José Gutiérrez de Quevedo -- Fixed rpm to create /var/hermes - -* Fri Apr 11 2007 Juan José Gutiérrez de Quevedo -- Initial release diff --git a/include/Configfile.h b/include/Configfile.h new file mode 100644 index 0000000..fa6c7c7 --- /dev/null +++ b/include/Configfile.h @@ -0,0 +1,144 @@ +/** + * hermes antispam proxy + * Copyright (C) 2006, 2007 Juan José Gutiérrez de Quevedo + * + * 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; version 2 of the License + * + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * @author Juan José Gutiérrez de Quevedo + */ +#ifndef CONFIGFILE_H +#define CONFIGFILE_H + +#include "hermes.h" +#include +#include +#include +#include + +#include "Utils.h" + +using namespace std; + +class Configfile +{ + private: + static string parseAsString(string); + static bool parseAsBool(string); + static long parseAsInt(string); + static list parseAsList(string); + int uid; + int gid; + bool background; +string chroot; +bool drop_privileges; +string user; +string group; +string pid_file; +int listening_port; +string bind_to; +string server_host; +int server_port; +string database_file; +bool greylist; +bool throttle; +int throttling_time; +int number_of_unimplemented_commands_allowed; +bool allow_data_before_banner; +list dns_blacklist_domains; +int dns_blacklist_percentage; +list dns_whitelist_domains; +int dns_whitelist_percentage; +bool add_status_header; +int banner_delay_time; +int initial_expiry; +int initial_blacklist; +int whitelist_expiry; +bool submit_stats; +bool submit_stats_ssl; +string submit_stats_username; +string submit_stats_password; +int log_level; +string file_logger_filename; +bool keep_file_locked; +int log_rotation_frequency; +string rotate_filename; +bool clean_db; +bool outgoing_ssl; +bool incoming_ssl; +string private_key_file; +string certificate_file; +string dhparams_file; +bool add_headers; +string hostname; +bool whitelisted_disables_everything; +bool reject_no_reverse_resolution; +bool check_helo_against_reverse; +bool query_spf; +bool return_temp_error_on_reject; + public: + Configfile(); + void parse(string); + void validateConfig(); + int getUid(); + int getGid(); + bool& getBackground(); +string& getChroot(); +bool& getDropPrivileges(); +string& getUser(); +string& getGroup(); +string& getPidFile(); +int& getListeningPort(); +string& getBindTo(); +string& getServerHost(); +int& getServerPort(); +string& getDatabaseFile(); +bool& getGreylist(); +bool& getThrottle(); +int& getThrottlingTime(); +int& getNumberOfUnimplementedCommandsAllowed(); +bool& getAllowDataBeforeBanner(); +list& getDnsBlacklistDomains(); +int& getDnsBlacklistPercentage(); +list& getDnsWhitelistDomains(); +int& getDnsWhitelistPercentage(); +bool& getAddStatusHeader(); +int& getBannerDelayTime(); +int& getInitialExpiry(); +int& getInitialBlacklist(); +int& getWhitelistExpiry(); +bool& getSubmitStats(); +bool& getSubmitStatsSsl(); +string& getSubmitStatsUsername(); +string& getSubmitStatsPassword(); +int& getLogLevel(); +string& getFileLoggerFilename(); +bool& getKeepFileLocked(); +int& getLogRotationFrequency(); +string& getRotateFilename(); +bool& getCleanDb(); +bool& getOutgoingSsl(); +bool& getIncomingSsl(); +string& getPrivateKeyFile(); +string& getCertificateFile(); +string& getDhparamsFile(); +bool& getAddHeaders(); +string& getHostname(); +bool& getWhitelistedDisablesEverything(); +bool& getRejectNoReverseResolution(); +bool& getCheckHeloAgainstReverse(); +bool& getQuerySpf(); +bool& getReturnTempErrorOnReject(); +}; + +#endif //CONFIGFILE_H diff --git a/src/Database.h b/include/Database.h similarity index 100% rename from src/Database.h rename to include/Database.h diff --git a/src/Exception.h b/include/Exception.h similarity index 100% rename from src/Exception.h rename to include/Exception.h diff --git a/src/FileLogger.h b/include/FileLogger.h similarity index 100% rename from src/FileLogger.h rename to include/FileLogger.h diff --git a/src/Logger.h b/include/Logger.h similarity index 100% rename from src/Logger.h rename to include/Logger.h diff --git a/src/NullLogger.h b/include/NullLogger.h similarity index 100% rename from src/NullLogger.h rename to include/NullLogger.h diff --git a/src/Proxy.h b/include/Proxy.h similarity index 63% rename from src/Proxy.h rename to include/Proxy.h index 689aebf..7e266c0 100644 --- a/src/Proxy.h +++ b/include/Proxy.h @@ -3,6 +3,11 @@ #include #include "SocketInterface.h" +#define SMTP_STATE_WAIT_FOR_HELO 0 +#define SMTP_STATE_WAIT_FOR_MAILFROM 1 +#define SMTP_STATE_WAIT_FOR_RCPTTO 2 +#define SMTP_STATE_WAIT_FOR_DATA 3 + class Proxy { public: Proxy(SocketInterface* outside_socket) : outside(outside_socket) {} diff --git a/src/ServerSocket.h b/include/ServerSocket.h similarity index 100% rename from src/ServerSocket.h rename to include/ServerSocket.h diff --git a/src/Socket.h b/include/Socket.h similarity index 100% rename from src/Socket.h rename to include/Socket.h diff --git a/src/SocketInterface.h b/include/SocketInterface.h similarity index 100% rename from src/SocketInterface.h rename to include/SocketInterface.h diff --git a/src/Spf.h b/include/Spf.h similarity index 100% rename from src/Spf.h rename to include/Spf.h diff --git a/src/UnixLogger.h b/include/UnixLogger.h similarity index 100% rename from src/UnixLogger.h rename to include/UnixLogger.h diff --git a/src/Utils.h b/include/Utils.h similarity index 100% rename from src/Utils.h rename to include/Utils.h diff --git a/src/hermes.h b/include/hermes.h similarity index 100% rename from src/hermes.h rename to include/hermes.h diff --git a/src/Configfile.cpp b/src/Configfile.cpp new file mode 100644 index 0000000..14900bd --- /dev/null +++ b/src/Configfile.cpp @@ -0,0 +1,314 @@ +/** + * hermes antispam proxy + * Copyright (C) 2006, 2007 Juan José Gutiérrez de Quevedo + * + * 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; version 2 of the License + * + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * @author Juan José Gutiérrez de Quevedo + */ +#include "Configfile.h" + +#include + +extern LOGGER_CLASS hermes_log; + +/** + * default config + * + */ +Configfile::Configfile() +{ +background=true; +chroot=""; +drop_privileges=true; +user="nobody"; +group="nobody"; +pid_file="/var/run/hermes.pid"; +listening_port=25; +bind_to=""; +server_host="localhost"; +server_port=2525; +database_file="/var/hermes/greylisting.db"; +greylist=true; +throttle=true; +throttling_time=1; +number_of_unimplemented_commands_allowed=-1; +allow_data_before_banner=false; +dns_blacklist_domains=Configfile::parseAsList(""); +dns_blacklist_percentage=100; +dns_whitelist_domains=Configfile::parseAsList(""); +dns_whitelist_percentage=100; +add_status_header=false; +banner_delay_time=5; +initial_expiry=240; +initial_blacklist=5; +whitelist_expiry=36; +submit_stats=true; +submit_stats_ssl=true; +submit_stats_username="anonymous"; +submit_stats_password="anonymous"; +log_level=1; +file_logger_filename="hermes.log"; +keep_file_locked=true; +log_rotation_frequency=1440; +rotate_filename="hermes-%%year%%-%%month%%-%%day%%-%%hour%%:%%minute%%.log"; +clean_db=true; +outgoing_ssl=false; +incoming_ssl=false; +private_key_file="/etc/hermes/hermes.key"; +certificate_file="/etc/hermes/hermes.cert"; +dhparams_file=""; +add_headers=true; +hostname=""; +whitelisted_disables_everything=true; +reject_no_reverse_resolution=false; +check_helo_against_reverse=false; +query_spf=false; +return_temp_error_on_reject=false; +} + +void Configfile::parse(string file) +{ + ifstream f; + char line[255]; + int equalpos; + + LINF("parsing "+Utils::get_canonical_filename(file)+" configuration file"); + f.open(file.c_str(),ios::in); + while(!f.eof()) + { + f.getline(line,255); + string l=Utils::trim(line); + if('#'!=l[0]&&l!=""&&l.find("=")) + { + equalpos=l.find("="); + string option=Utils::trim(l.substr(0,equalpos)); + string value=Utils::trim(l.substr(equalpos+1)); + //if(false==cfg.getBackground()) + // cout << option << " -> " << value << endl; + + //this is a bit of a hack, but simplifies a lot this function + #define PARSE_INT(x,y) if(x==option) y=Configfile::parseAsInt(value); else + #define PARSE_BOOL(x,y) if(x==option) y=Configfile::parseAsBool(value); else + #define PARSE_STRING(x,y) if(x==option) y=Configfile::parseAsString(value); else + #define PARSE_LIST(x,y) if(x==option) y=Configfile::parseAsList(value); else + + PARSE_BOOL("background",background) +PARSE_STRING("chroot",chroot) +PARSE_BOOL("drop_privileges",drop_privileges) +PARSE_STRING("user",user) +PARSE_STRING("group",group) +PARSE_STRING("pid_file",pid_file) +PARSE_INT("listening_port",listening_port) +PARSE_STRING("bind_to",bind_to) +PARSE_STRING("server_host",server_host) +PARSE_INT("server_port",server_port) +PARSE_STRING("database_file",database_file) +PARSE_BOOL("greylist",greylist) +PARSE_BOOL("throttle",throttle) +PARSE_INT("throttling_time",throttling_time) +PARSE_INT("number_of_unimplemented_commands_allowed",number_of_unimplemented_commands_allowed) +PARSE_BOOL("allow_data_before_banner",allow_data_before_banner) +PARSE_LIST("dns_blacklist_domains",dns_blacklist_domains) +PARSE_INT("dns_blacklist_percentage",dns_blacklist_percentage) +PARSE_LIST("dns_whitelist_domains",dns_whitelist_domains) +PARSE_INT("dns_whitelist_percentage",dns_whitelist_percentage) +PARSE_BOOL("add_status_header",add_status_header) +PARSE_INT("banner_delay_time",banner_delay_time) +PARSE_INT("initial_expiry",initial_expiry) +PARSE_INT("initial_blacklist",initial_blacklist) +PARSE_INT("whitelist_expiry",whitelist_expiry) +PARSE_BOOL("submit_stats",submit_stats) +PARSE_BOOL("submit_stats_ssl",submit_stats_ssl) +PARSE_STRING("submit_stats_username",submit_stats_username) +PARSE_STRING("submit_stats_password",submit_stats_password) +PARSE_INT("log_level",log_level) +PARSE_STRING("file_logger_filename",file_logger_filename) +PARSE_BOOL("keep_file_locked",keep_file_locked) +PARSE_INT("log_rotation_frequency",log_rotation_frequency) +PARSE_STRING("rotate_filename",rotate_filename) +PARSE_BOOL("clean_db",clean_db) +PARSE_BOOL("outgoing_ssl",outgoing_ssl) +PARSE_BOOL("incoming_ssl",incoming_ssl) +PARSE_STRING("private_key_file",private_key_file) +PARSE_STRING("certificate_file",certificate_file) +PARSE_STRING("dhparams_file",dhparams_file) +PARSE_BOOL("add_headers",add_headers) +PARSE_STRING("hostname",hostname) +PARSE_BOOL("whitelisted_disables_everything",whitelisted_disables_everything) +PARSE_BOOL("reject_no_reverse_resolution",reject_no_reverse_resolution) +PARSE_BOOL("check_helo_against_reverse",check_helo_against_reverse) +PARSE_BOOL("query_spf",query_spf) +PARSE_BOOL("return_temp_error_on_reject",return_temp_error_on_reject) + { + throw Exception("Option \""+option+"\" with value \""+value+"\" is not recognized",__FILE__,__LINE__); + } + #undef PARSE_INT + #undef PARSE_BOOL + #undef PARSE_STRING + #undef PARSE_LIST + } + } + #ifndef WIN32 + uid=Utils::usertouid(user); + gid=Utils::grouptogid(group); + #endif //WIN32 + f.close(); +} + +//again, this is a BIG HACK, but it simplifies code a lot +#define GET_VAR(x,y,z) z Configfile::x(){ return y;} + +GET_VAR(getUid,uid,int) +GET_VAR(getGid,gid,int) +GET_VAR(getBackground,background,bool&) +GET_VAR(getChroot,chroot,string&) +GET_VAR(getDropPrivileges,drop_privileges,bool&) +GET_VAR(getUser,user,string&) +GET_VAR(getGroup,group,string&) +GET_VAR(getPidFile,pid_file,string&) +GET_VAR(getListeningPort,listening_port,int&) +GET_VAR(getBindTo,bind_to,string&) +GET_VAR(getServerHost,server_host,string&) +GET_VAR(getServerPort,server_port,int&) +GET_VAR(getDatabaseFile,database_file,string&) +GET_VAR(getGreylist,greylist,bool&) +GET_VAR(getThrottle,throttle,bool&) +GET_VAR(getThrottlingTime,throttling_time,int&) +GET_VAR(getNumberOfUnimplementedCommandsAllowed,number_of_unimplemented_commands_allowed,int&) +GET_VAR(getAllowDataBeforeBanner,allow_data_before_banner,bool&) +GET_VAR(getDnsBlacklistDomains,dns_blacklist_domains,list&) +GET_VAR(getDnsBlacklistPercentage,dns_blacklist_percentage,int&) +GET_VAR(getDnsWhitelistDomains,dns_whitelist_domains,list&) +GET_VAR(getDnsWhitelistPercentage,dns_whitelist_percentage,int&) +GET_VAR(getAddStatusHeader,add_status_header,bool&) +GET_VAR(getBannerDelayTime,banner_delay_time,int&) +GET_VAR(getInitialExpiry,initial_expiry,int&) +GET_VAR(getInitialBlacklist,initial_blacklist,int&) +GET_VAR(getWhitelistExpiry,whitelist_expiry,int&) +GET_VAR(getSubmitStats,submit_stats,bool&) +GET_VAR(getSubmitStatsSsl,submit_stats_ssl,bool&) +GET_VAR(getSubmitStatsUsername,submit_stats_username,string&) +GET_VAR(getSubmitStatsPassword,submit_stats_password,string&) +GET_VAR(getLogLevel,log_level,int&) +GET_VAR(getFileLoggerFilename,file_logger_filename,string&) +GET_VAR(getKeepFileLocked,keep_file_locked,bool&) +GET_VAR(getLogRotationFrequency,log_rotation_frequency,int&) +GET_VAR(getRotateFilename,rotate_filename,string&) +GET_VAR(getCleanDb,clean_db,bool&) +GET_VAR(getOutgoingSsl,outgoing_ssl,bool&) +GET_VAR(getIncomingSsl,incoming_ssl,bool&) +GET_VAR(getPrivateKeyFile,private_key_file,string&) +GET_VAR(getCertificateFile,certificate_file,string&) +GET_VAR(getDhparamsFile,dhparams_file,string&) +GET_VAR(getAddHeaders,add_headers,bool&) +GET_VAR(getHostname,hostname,string&) +GET_VAR(getWhitelistedDisablesEverything,whitelisted_disables_everything,bool&) +GET_VAR(getRejectNoReverseResolution,reject_no_reverse_resolution,bool&) +GET_VAR(getCheckHeloAgainstReverse,check_helo_against_reverse,bool&) +GET_VAR(getQuerySpf,query_spf,bool&) +GET_VAR(getReturnTempErrorOnReject,return_temp_error_on_reject,bool&) + +#undef GET_VAR + +void Configfile::validateConfig() +{ + #ifndef WIN32 + //check if we are root if we want to bind to a port lower than 1024 + if(getuid()!=0&&listening_port<1024) + throw Exception(_("You can't bind to a port lower than 1024 without being root"),__FILE__,__LINE__); + #endif //WIN32 + + #ifdef HAVE_SSL + //check if ssl is usable + if(!Utils::file_exists(certificate_file)) + throw Exception("Certificate file "+certificate_file+" doesn't exist.\nTo generate a certificate look in hermesrc.example, there is an example there.",__FILE__,__LINE__); + + if(!Utils::file_exists(private_key_file)) + throw Exception("Private key file "+private_key_file+" doesn't exist.\nTo generate a private key look in hermesrc.example, there is an example there.",__FILE__,__LINE__); + #endif //HAVE_SSL + + #ifndef WIN32 + //check if chroot dir exist //TODO: check that files needed in chroot exist + //for now only /etc/resolv.conf, but we're working on it :-D + if(""!=chroot&&!Utils::dir_exists(chroot)) + throw Exception("Directory "+chroot+" doesn't exist, can't chroot to it.",__FILE__,__LINE__); + #endif //WIN32 + + //check if we have submit_stats on but no user and password + if(getSubmitStats()&&(""==getSubmitStatsUsername()||""==getSubmitStatsPassword())) + throw Exception("You have configured hermes to send stats, but have not configured a username or password.\n" + "If you don't have one, go to http://www.hermes-project.com and register there",__FILE__,__LINE__); + + #ifndef HAVE_SSL + //check if we have activated submit_stats_ssl not having ssl activated + if(getSubmitStatsSsl()) + throw Exception("You have configured stats submission through SSL, but hermes was compiled without SSL support",__FILE__,__LINE__); + #endif //HAVE_SSL + +} + +string Configfile::parseAsString(string str) +{ + //remove "" round the string + if('"'==str[0]) + str=str.substr(1); + if('"'==str[str.length()-1]) + str=str.substr(0,str.length()-1); + + return str; +} + +bool Configfile::parseAsBool(string str) +{ + if("yes"==str||"on"==str||"1"==str||"true"==str) + return true; + else + return false; +} + +long int Configfile::parseAsInt(string str) +{ + long int value; + + errno=0; //to know why we do this, read NOTES on strtol(3) + value=strtol(str.c_str(),NULL,10); + if(errno) + throw Exception("Error parsing as int ("+Utils::errnotostrerror(errno)+")",__FILE__,__LINE__); + + return value; +} + +list Configfile::parseAsList(string str) +{ + list tmpList; + string::size_type startpos=0,endpos=0,len; + string tmpstr; + + str=Configfile::parseAsString(str); //remove quotes around string + + len=str.length(); + while(startpos