From a78b44b50cc7d8d7e75eac32430dfbfba55c5942 Mon Sep 17 00:00:00 2001 From: Bjoern Sikora Date: Tue, 8 Sep 2009 19:08:55 +0200 Subject: [PATCH] Added implementation of gnudip protocol. Added util class to compute md5 sum (wrapper class which uses high level C interface openssl/evp.h). Adapted all perform_update member functions. --- src/config.cpp | 37 +++++- src/config.h | 2 +- src/logger.cpp | 63 ++++++++++- src/logger.h | 8 ++ src/main.cpp | 2 + src/service_dhs.cpp | 10 +- src/service_dyndns.cpp | 16 ++- src/service_dyns.cpp | 16 ++- src/service_easydns.cpp | 16 ++- src/service_gnudip.cpp | 287 ++++++++++++++++++++++++++++++++++++++++++++++ src/service_gnudip.h | 55 +++++++++ src/service_tzo.cpp | 16 ++- src/service_zoneedit.cpp | 14 ++- src/updater.cpp | 2 + src/util.cpp | 58 +++++++++ src/util.h | 29 +++++ 16 files changed, 599 insertions(+), 32 deletions(-) create mode 100644 src/service_gnudip.cpp create mode 100644 src/service_gnudip.h create mode 100644 src/util.cpp create mode 100644 src/util.h diff --git a/src/config.cpp b/src/config.cpp index 08b44fa..a8635f8 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -16,6 +16,7 @@ #include "service_easydns.h" #include "service_tzo.h" #include "service_zoneedit.h" +#include "service_gnudip.h" #include #include @@ -52,6 +53,7 @@ Config::Config(Logger::Ptr _log, Serviceholder::Ptr _serviceholder) po::options_description opt_desc_service("Service description options"); opt_desc_service.add_options() ("protocol",po::value(),"The service protocol.") + ("server",po::value(),"Servername needed for gnudip protocol.") ("host",po::value(),"The hostname to update.") ("login",po::value(),"Login name.") ("password",po::value(),"Corresponding password.") @@ -148,6 +150,10 @@ int Config::parse_cmd_line(int argc, char *argv[]) protocol = ba::to_lower_copy(protocol); + string server; + if ( VariablesMap.count("server") ) + server = VariablesMap["server"].as(); + int update_interval = 0; if ( VariablesMap.count("update_interval") ) update_interval = VariablesMap["update_interval"].as(); @@ -160,7 +166,7 @@ int Config::parse_cmd_line(int argc, char *argv[]) if ( VariablesMap.count("dns_cache_ttl") ) dns_cache_ttl = VariablesMap["dns_cache_ttl"].as(); - Service::Ptr service = create_service(protocol,host,login,password,update_interval,max_updates_within_interval,dns_cache_ttl); + Service::Ptr service = create_service(protocol,server,host,login,password,update_interval,max_updates_within_interval,dns_cache_ttl); if ( service ) { ServiceHolder->add_service(service); @@ -249,7 +255,7 @@ int Config::parse_cmd_line(int argc, char *argv[]) * @param password Password. * @return A pointer to the created Service object. */ -Service::Ptr Config::create_service(const string &protocol,const string &hostname, const string &login, const string &password, const int update_interval, const int max_updates_within_interval, const int dns_cache_ttl) +Service::Ptr Config::create_service(const string &protocol, const string& server, const string& hostname, const string& login, const string& password, const int update_interval, const int max_updates_within_interval, const int dns_cache_ttl) { // Test for valid hostname. Must contain 3 parts minimum. list fqhn_parts; @@ -296,6 +302,21 @@ Service::Ptr Config::create_service(const string &protocol,const string &hostnam Service::Ptr service_zoneedit(new ServiceZoneedit(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); return service_zoneedit; } + else if(protocol == "gnudip") + { + cout << "Server: " << server << endl; + if ( !server.empty() ) + { + Service::Ptr service_gnudip(new ServiceGnudip(protocol,server,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); + return service_gnudip; + } + else + { + Log->print_gnudip_requires_servername(); + Service::Ptr service; + return service; + } + } else { Log->print_unknown_protocol(protocol); @@ -334,19 +355,23 @@ int Config::load_service_config_file(const string& full_filename) protocol = ba::to_lower_copy(protocol); + string server; + if ( vm.count("server") ) + server = vm["server"].as(); + int update_interval = 0; if ( vm.count("update_interval") ) - update_interval = VariablesMap["update_interval"].as(); + update_interval = vm["update_interval"].as(); int max_updates_within_interval = 0; if ( vm.count("max_updates_within_interval") ) - max_updates_within_interval = VariablesMap["max_updates_within_interval"].as(); + max_updates_within_interval = vm["max_updates_within_interval"].as(); int dns_cache_ttl = 0; if ( vm.count("dns_cache_ttl") ) - dns_cache_ttl = VariablesMap["dns_cache_ttl"].as(); + dns_cache_ttl = vm["dns_cache_ttl"].as(); - Service::Ptr service = create_service(protocol,host,login,password,update_interval,max_updates_within_interval,dns_cache_ttl); + Service::Ptr service = create_service(protocol,server,host,login,password,update_interval,max_updates_within_interval,dns_cache_ttl); if ( service ) { ServiceHolder->add_service(service); diff --git a/src/config.h b/src/config.h index 712eb8b..9365340 100644 --- a/src/config.h +++ b/src/config.h @@ -47,7 +47,7 @@ private: std::string ExternalWarningLog; int ExternalWarningLevel; - Service::Ptr create_service(const std::string &protocol,const std::string &hostname, const std::string &login, const std::string &password, const int update_interval, const int max_updates_within_interval, const int dns_cache_ttl); + Service::Ptr create_service(const std::string& protocol, const std::string& server, const std::string& hostname, const std::string& login, const std::string& password, const int update_interval, const int max_updates_within_interval, const int dns_cache_ttl); int load_main_config_file(const std::string& full_filename); int load_service_config_file(const std::string& full_filename); diff --git a/src/logger.cpp b/src/logger.cpp index 6c6185a..f413b9a 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -71,6 +71,7 @@ void Logger::log_warning(const string& msg, int level) const external.append(msg); external.append("\""); int ret_val = system(external.c_str()); + // TODO: parse return code and error handling } } @@ -1359,7 +1360,7 @@ void Logger::print_ip_is_local(const string& ip) const * @param regex The regex pattern * @param matching_string The string */ -void Logger::print_regex_match(const std::string& regex, const std::string& matching_string) const +void Logger::print_regex_match(const string& regex, const string& matching_string) const { int level = 1; if ( (level <= Loglevel) || ((level <= ExternalWarningLevel) && (!ExternalWarningLog.empty())) ) @@ -1369,3 +1370,63 @@ void Logger::print_regex_match(const std::string& regex, const std::string& matc log_notice(msg.str(),level); } } + + +/** + * Regex is not matching + * @param regex Regex + * @param not_matching_string String + */ +void Logger::print_no_regex_match(const string& regex, const string& not_matching_string) const +{ + int level = 1; + if ( (level <= Loglevel) || ((level <= ExternalWarningLevel) && (!ExternalWarningLog.empty())) ) + { + ostringstream msg; + msg << "Regex: " << regex << " is not matching in: " << not_matching_string << endl; + log_warning(msg.str(),level); + } +} + + +/** + * Could not parse gnudip initial reply. + * @param curl_data The data received from gnudip server which should contain salt, time and sign. + */ +void Logger::print_could_not_parse_received_data(const string& curl_data) const +{ + int level = 0; + if ( (level <= Loglevel) || ((level <= ExternalWarningLevel) && (!ExternalWarningLog.empty())) ) + { + ostringstream msg; + msg << "Could not parse salt, time and sign from initial gnudip server reply: " << curl_data << endl; + log_warning(msg.str(),level); + } +} + + +/** + * Gnudip salt, time and sign could not be got from map + */ +void Logger::print_could_not_get_initial_gnudip_data() const +{ + int level = 0; + if ( (level <= Loglevel) || ((level <= ExternalWarningLevel) && (!ExternalWarningLog.empty())) ) + { + ostringstream msg; + msg << "Could not get salt, time and sign from map." << endl; + log_warning(msg.str(),level); + } +} + + +void Logger::print_gnudip_requires_servername() const +{ + int level = 0; + if ( (level <= Loglevel) || ((level <= ExternalWarningLevel) && (!ExternalWarningLog.empty())) ) + { + ostringstream msg; + msg << "Gnudip requires explicit definition of servername via config!" << endl; + log_warning(msg.str(),level); + } +} diff --git a/src/logger.h b/src/logger.h index 9a6fb43..61f7055 100644 --- a/src/logger.h +++ b/src/logger.h @@ -199,6 +199,14 @@ public: void print_ip_is_local(const std::string& ip) const; void print_regex_match(const std::string& regex, const std::string& matching_string) const; + + void print_no_regex_match(const std::string& regex, const std::string& not_matching_string) const; + + void print_could_not_parse_received_data(const std::string& curl_data) const; + + void print_could_not_get_initial_gnudip_data() const; + + void print_gnudip_requires_servername() const; }; #endif diff --git a/src/main.cpp b/src/main.cpp index a7b9719..a45dca2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,7 @@ #include "iphelper.cpp" #include "httphelper.cpp" #include "serializeservicecontainer.cpp" +#include "util.cpp" #include "service_dyndns.cpp" #include "service_dyns.cpp" @@ -44,6 +45,7 @@ #include "service_easydns.cpp" #include "service_tzo.cpp" #include "service_zoneedit.cpp" +#include "service_gnudip.cpp" using namespace std; diff --git a/src/service_dhs.cpp b/src/service_dhs.cpp index a9486bc..e0ac01d 100644 --- a/src/service_dhs.cpp +++ b/src/service_dhs.cpp @@ -136,8 +136,6 @@ list ServiceDhs::separate_domain_and_host_part(const string& fqdn) const */ int ServiceDhs::perform_update(const std::string& ip) { - int ret_val = -1; - string url = BaseUrl; url.append(ip); @@ -150,14 +148,18 @@ int ServiceDhs::perform_update(const std::string& ip) if ( http_status_code == 200 ) { // TODO: Account related errors should be handled here! - ret_val = 0; + return 0; } else if ( http_status_code == 401 ) + { get_logger()->print_http_not_authorized(url,get_login(),get_password()); + } else + { get_logger()->print_update_failure(url,http_status_code); + } - return ret_val; + return -1; } diff --git a/src/service_dyndns.cpp b/src/service_dyndns.cpp index fa9fcc1..74dafb4 100644 --- a/src/service_dyndns.cpp +++ b/src/service_dyndns.cpp @@ -94,8 +94,6 @@ string ServiceDyndns::assemble_base_url(const string& fqhn) const */ int ServiceDyndns::perform_update(const std::string& ip) { - int ret_val = -1; - // the result string if update was successful string good = "good "; good.append(ip); @@ -117,14 +115,24 @@ int ServiceDyndns::perform_update(const std::string& ip) string curl_data = HTTPHelp->get_curl_data(); if ( curl_data == good ) - ret_val = 0; + { + return 0; + } else if ( curl_data == "badauth" ) + { get_logger()->print_http_not_authorized(url,get_login(),get_password()); + } else + { get_logger()->print_update_failure(url, curl_data); + } + } + else + { + get_logger()->print_update_failure(url,http_status_code); } - return ret_val; + return -1; } diff --git a/src/service_dyns.cpp b/src/service_dyns.cpp index ed43578..00e85fc 100644 --- a/src/service_dyns.cpp +++ b/src/service_dyns.cpp @@ -103,8 +103,6 @@ string ServiceDyns::assemble_base_url(const string& fqhn, const string& username */ int ServiceDyns::perform_update(const std::string& ip) { - int ret_val = -1; - string url = BaseUrl; url.append(ip); @@ -122,14 +120,24 @@ int ServiceDyns::perform_update(const std::string& ip) string status_code = parse_status_code(curl_data); if ( status_code == "200" ) - ret_val = 0; + { + return 0; + } else if ( status_code == "401" ) + { get_logger()->print_http_not_authorized(url,get_login(),get_password()); + } else + { get_logger()->print_update_failure(url,curl_data); + } + } + else + { + get_logger()->print_update_failure(url,http_status_code); } - return ret_val; + return -1; } diff --git a/src/service_easydns.cpp b/src/service_easydns.cpp index daf0584..ca19579 100644 --- a/src/service_easydns.cpp +++ b/src/service_easydns.cpp @@ -183,8 +183,6 @@ list ServiceEasydns::separate_domain_and_host_part(const string& fqdn) c */ int ServiceEasydns::perform_update(const std::string& ip) { - int ret_val = -1; - string url = BaseUrl; url.append(ip); @@ -201,14 +199,24 @@ int ServiceEasydns::perform_update(const std::string& ip) string curl_data = HTTPHelp->get_curl_data(); if ( curl_data == "NOERROR" ) - ret_val = 0; + { + return 0; + } else if ( curl_data == "NOACCESS" ) + { get_logger()->print_http_not_authorized(url,get_login(),get_password()); + } else + { get_logger()->print_update_failure(url, curl_data); + } + } + else + { + get_logger()->print_update_failure(url,http_status_code); } - return ret_val; + return -1; } diff --git a/src/service_gnudip.cpp b/src/service_gnudip.cpp new file mode 100644 index 0000000..7109b6a --- /dev/null +++ b/src/service_gnudip.cpp @@ -0,0 +1,287 @@ +/** @file + * @brief GNUDIP Service class implementation. This class represents the GNUDIP service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#include "service_gnudip.h" +#include "util.h" + +#include +#include +#include + +using namespace std; + + +/** + * Default Constructor, needed for object serialization. + */ +ServiceGnudip::ServiceGnudip() +{ +} + + +/** + * Constructor. + * @param _hostname The hostname to update + * @param _login The login name. + * @param _password The corresponding password. + */ +ServiceGnudip::ServiceGnudip(const string& _protocol, const string& _gnudip_server, const string& _hostname, const string& _login, const string& _password, const Logger::Ptr& _logger, const int _update_interval, const int _max_updates_within_interval, const int _dns_cache_ttl, const string& _proxy, const int _proxy_port) + : GnudipServer(_gnudip_server) +{ + if ( _update_interval == -1 ) // If _update_interval is default po::option_desc (not specified via config) + set_update_interval(0); // use default protocol value + else + set_update_interval(_update_interval); + + if ( _max_updates_within_interval == -1 ) + set_max_updates_within_interval(0); + else + set_max_updates_within_interval(_max_updates_within_interval); + + if ( _dns_cache_ttl == -1 ) + set_dns_cache_ttl(60); + else + set_dns_cache_ttl(_dns_cache_ttl); + + set_protocol(_protocol); + set_hostname(_hostname); + set_login(_login); + set_password(_password); + set_logger(_logger); + + // create http helper class + HTTPHelper::Ptr _http_help(new HTTPHelper(_logger,_proxy,_proxy_port,_login,_password)); + HTTPHelp = _http_help; + _http_help.reset(); + + BaseUrl = assemble_base_url(get_hostname(),_gnudip_server); +} + + +/** + * Default destructor + */ +ServiceGnudip::~ServiceGnudip() +{ +} + + +/** + * Assemble the dyndns update url from the given fqhn + * @param hostname The fqhn hostname to update IP for. + * @return The assembled update url without IP. + */ +string ServiceGnudip::assemble_base_url(const string& fqhn, const string& gnudip_server) const +{ + string base_url; + + base_url = "http://"; + base_url.append(gnudip_server); + base_url.append("/gnudip/cgi-bin/gdipupdt.cgi"); + + return base_url; +} + + +/** + * Parses the data received from the initial request, which should contain salt, time and sign. + * @param curl_data The complete received curl data. + * @return A map with salt, time and sign or an empty map. + */ +map ServiceGnudip::parse_initial_request(const string& curl_data) const +{ + map response; + + // regex for salt + boost::regex expr_salt(""); + // regex for time + boost::regex expr_time(""); + // regex for sign + boost::regex expr_sign(""); + + boost::smatch matches; + + // Get the salt out of received http data + if ( boost::regex_search(curl_data,matches,expr_salt) ) + { + response.insert(pair("salt",matches[1])); + get_logger()->print_regex_match(expr_salt.str(),matches[1]); + } + else + { + get_logger()->print_no_regex_match(expr_salt.str(),curl_data); + response.clear(); + return response; + } + + // Get the time out of received http data + if ( boost::regex_search(curl_data,matches,expr_time) ) + { + response.insert(pair("time",matches[1])); + get_logger()->print_regex_match(expr_salt.str(),matches[1]); + } + else + { + get_logger()->print_no_regex_match(expr_salt.str(),curl_data); + response.clear(); + return response; + } + + // Get the sign out of received http data + if ( boost::regex_search(curl_data,matches,expr_sign) ) + { + response.insert(pair("sign",matches[1])); + get_logger()->print_regex_match(expr_salt.str(),matches[1]); + } + else + { + get_logger()->print_no_regex_match(expr_salt.str(),curl_data); + response.clear(); + return response; + } + + return response; +} + + +/** + * Get the assembled update url. + * @param salt Salt from the initial request + * @param time Time from the initial request + * @param sign Sign from the initial request + * @param secret Computed md5 secret in HEX + * @param ip IP to update + * @return The assembled update url. + */ +string ServiceGnudip::assemble_update_url(const string& salt, const string& time, const string& sign, const string& secret, const string& ip) const +{ + string url = BaseUrl; + + url.append("?salt="); + url.append(salt); + url.append("&time="); + url.append(time); + url.append("&sign="); + url.append(sign); + url.append("&user="); + url.append(get_login()); + url.append("&domn="); + url.append(get_hostname()); + url.append("&pass="); + url.append(secret); + url.append("&reqc=0&addr="); + url.append(ip); + + return url; +} + + +/** + * Performs the Service update. + * @param ip IP Address to set. + * @return 0 if all is fine, -1 otherwise. + */ +int ServiceGnudip::perform_update(const std::string& ip) +{ + // initial request + long http_status_code = HTTPHelp->http_get(BaseUrl); + + get_logger()->print_http_status_code(BaseUrl,http_status_code); + + if ( http_status_code == 200 ) + { + // Get the received http data which should contain the salt, time and sign + string curl_data = HTTPHelp->get_curl_data(); + + // Parse salt, time and sign out of the received data + map salt_time_sign = parse_initial_request(curl_data); + + if ( salt_time_sign.empty() ) + { + get_logger()->print_could_not_parse_received_data(curl_data); + return -1; + } + + // at this point we have salt, time and sign parsed successfully + string salt, time, sign; + + map::iterator iter = salt_time_sign.find("salt"); + if ( iter != salt_time_sign.end() ) + salt = iter->second; + + iter = salt_time_sign.find("time"); + if ( iter != salt_time_sign.end() ) + time = iter->second; + + iter = salt_time_sign.find("sign"); + if ( iter != salt_time_sign.end() ) + sign = iter->second; + + if ( salt.empty() || time.empty() || sign.empty() ) + get_logger()->print_could_not_get_initial_gnudip_data(); + + // compute md5 sum from users password and get the HEX representation + string pw_md5_hex = Util::compute_md5_digest(get_password()); + + // append "." and salt and compute md5 sum and get the HEX representation + pw_md5_hex.append("."); + pw_md5_hex.append(salt); + string secret = Util::compute_md5_digest(pw_md5_hex); + + // Now its time to issue the second http_get operation + string url = assemble_update_url(salt, time, sign, secret, ip); + + // perform the update operation + http_status_code = HTTPHelp->http_get(url); + + get_logger()->print_http_status_code(url,http_status_code); + + if ( http_status_code == 200 ) + { + // parse the update request return code + string update_return_code = HTTPHelp->get_curl_data(); + if ( update_return_code == "0" ) + { + return 0; + } + else if ( update_return_code == "1" ) + { + get_logger()->print_http_not_authorized(url,get_login(),get_password()); + } + else + { + get_logger()->print_update_failure(url,update_return_code); + } + } + else + { + // second http get operation (update) was not successful + get_logger()->print_update_failure(url,http_status_code); + } + } + else + { + // first http get operation was not successful + get_logger()->print_update_failure(BaseUrl,http_status_code); + } + + return -1; +} + + +/** + * Serialize function needed by boost/serialization to define which members should be stored as the object state. + * @param ar Archive + * @param version Version + */ +template +void ServiceGnudip::serialize(Archive & ar, const unsigned int version) +{ + ar & boost::serialization::base_object(*this); +} diff --git a/src/service_gnudip.h b/src/service_gnudip.h new file mode 100644 index 0000000..8e6306f --- /dev/null +++ b/src/service_gnudip.h @@ -0,0 +1,55 @@ +/** @file + * @brief GNUDIP Service class header. This class represents the GNUDIP service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#ifndef ServiceGnudip_H +#define ServiceGnudip_H + +#include + +#include "service.h" +#include "logger.h" + +#include +#include +#include +#include + +class ServiceGnudip : public Service +{ + +private: + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version); + + std::string GnudipServer; + std::string BaseUrl; + + HTTPHelper::Ptr HTTPHelp; + + std::string assemble_base_url(const std::string& fqhn, const std::string& gnudip_server) const; + std::map parse_initial_request(const std::string& curl_data) const; + std::string assemble_update_url(const std::string& salt, const std::string& time, const std::string& sign, const std::string& secret, const std::string& ip) const; + +public: + + typedef boost::shared_ptr Ptr; + + ServiceGnudip(); + + ServiceGnudip(const std::string& _protocol, const std::string& _gnudip_server ,const std::string& _hostname, const std::string& _login, const std::string& _password, const Logger::Ptr& _logger, const int _update_interval, const int _max_updates_within_interval, const int dns_cache_ttl, const std::string& proxy, const int proxy_port); + + ~ServiceGnudip(); + + int perform_update(const std::string& ip); + +}; + +#endif diff --git a/src/service_tzo.cpp b/src/service_tzo.cpp index 9bd0e6a..31b7c57 100644 --- a/src/service_tzo.cpp +++ b/src/service_tzo.cpp @@ -103,8 +103,6 @@ string ServiceTzo::assemble_base_url(const string& fqhn, const string& username, */ int ServiceTzo::perform_update(const std::string& ip) { - int ret_val = -1; - string url = BaseUrl; url.append(ip); @@ -122,14 +120,24 @@ int ServiceTzo::perform_update(const std::string& ip) string status_code = parse_status_code(curl_data); if ( status_code == "200" ) - ret_val = 0; + { + return 0; + } else if ( status_code == "401" ) + { get_logger()->print_http_not_authorized(url,get_login(),get_password()); + } else + { get_logger()->print_update_failure(url,curl_data); + } + } + else + { + get_logger()->print_update_failure(url,http_status_code); } - return ret_val; + return -1; } diff --git a/src/service_zoneedit.cpp b/src/service_zoneedit.cpp index c407526..47e5e8d 100644 --- a/src/service_zoneedit.cpp +++ b/src/service_zoneedit.cpp @@ -97,8 +97,6 @@ string ServiceZoneedit::assemble_base_url(const string& fqhn) const */ int ServiceZoneedit::perform_update(const std::string& ip) { - int ret_val = -1; - string url = BaseUrl; url.append(ip); @@ -116,16 +114,24 @@ int ServiceZoneedit::perform_update(const std::string& ip) string status_code = parse_status_code(curl_data); if ( status_code == "200" ) - ret_val = 0; + { + return 0; + } else + { get_logger()->print_update_failure(url,curl_data); + } } else if ( http_status_code == 401 ) + { get_logger()->print_http_not_authorized(url,get_login(),get_password()); + } else + { get_logger()->print_update_failure(url,http_status_code); + } - return ret_val; + return -1; } diff --git a/src/updater.cpp b/src/updater.cpp index 54b3793..30e160a 100644 --- a/src/updater.cpp +++ b/src/updater.cpp @@ -17,6 +17,7 @@ #include "service_easydns.h" #include "service_tzo.h" #include "service_zoneedit.h" +#include "service_gnudip.h" #include @@ -29,6 +30,7 @@ BOOST_CLASS_EXPORT_GUID(ServiceDyndns, "ServiceDyndns") BOOST_CLASS_EXPORT_GUID(ServiceEasydns, "ServiceEasydns") BOOST_CLASS_EXPORT_GUID(ServiceTzo, "ServiceTzo") BOOST_CLASS_EXPORT_GUID(ServiceZoneedit, "ServiceZoneedit") +BOOST_CLASS_EXPORT_GUID(ServiceGnudip, "ServiceGnudip") namespace fs = boost::filesystem; diff --git a/src/util.cpp b/src/util.cpp new file mode 100644 index 0000000..1f10ce8 --- /dev/null +++ b/src/util.cpp @@ -0,0 +1,58 @@ +/** @file + * @brief Util class implementation. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#include "util.h" + +#include +#include +#include + +Util::Util() +{ +} + +Util::~Util() +{ +} + +/** + * Computes a MD5 Digest from the given string and returns the HEX representation + * @param data The string to compute the md5 for + * @return The computed md5 in hex + */ +std::string Util::compute_md5_digest(std::string data) +{ + // compute an MD5 digest. + + string result; + EVP_MD_CTX mdctx; + const EVP_MD *md; + unsigned char md_value[EVP_MAX_MD_SIZE]; + unsigned int md_len; + + OpenSSL_add_all_digests(); + + md = EVP_get_digestbyname("md5"); + + EVP_MD_CTX_init(&mdctx); + EVP_DigestInit_ex(&mdctx, md, NULL); + EVP_DigestUpdate(&mdctx, data.c_str(), strlen(data.c_str())); + EVP_DigestFinal_ex(&mdctx, md_value, &md_len); + EVP_MD_CTX_cleanup(&mdctx); + + char buffer[2]; + + for(int i = 0; i < md_len; i++) + { + sprintf(buffer,"%02x", md_value[i]); + result.append(buffer); + } + + return result; +} diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..43321de --- /dev/null +++ b/src/util.h @@ -0,0 +1,29 @@ +/** @file + * @brief Util class header. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#ifndef UTIL_H +#define UTIL_H + + +class Util +{ +private: + + +public: + + Util(); + + ~Util(); + + static std::string compute_md5_digest(std::string); + +}; + +#endif -- 1.7.1