Added implementation of gnudip protocol.
authorBjoern Sikora <bjoern.sikora@intra2net.com>
Tue, 8 Sep 2009 17:08:55 +0000 (19:08 +0200)
committerBjoern Sikora <bjoern.sikora@intra2net.com>
Tue, 8 Sep 2009 17:08:55 +0000 (19:08 +0200)
Added util class to compute md5 sum (wrapper class which uses high level C interface openssl/evp.h).
Adapted all perform_update member functions.

16 files changed:
src/config.cpp
src/config.h
src/logger.cpp
src/logger.h
src/main.cpp
src/service_dhs.cpp
src/service_dyndns.cpp
src/service_dyns.cpp
src/service_easydns.cpp
src/service_gnudip.cpp [new file with mode: 0644]
src/service_gnudip.h [new file with mode: 0644]
src/service_tzo.cpp
src/service_zoneedit.cpp
src/updater.cpp
src/util.cpp [new file with mode: 0644]
src/util.h [new file with mode: 0644]

index 08b44fa..a8635f8 100644 (file)
@@ -16,6 +16,7 @@
 #include "service_easydns.h"
 #include "service_tzo.h"
 #include "service_zoneedit.h"
+#include "service_gnudip.h"
 
 #include <time.h>
 #include <iostream>
@@ -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<string>(),"The service protocol.")
+        ("server",po::value<string>(),"Servername needed for gnudip protocol.")
         ("host",po::value<string>(),"The hostname to update.")
         ("login",po::value<string>(),"Login name.")
         ("password",po::value<string>(),"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<string>();
+
             int update_interval = 0;
             if ( VariablesMap.count("update_interval") )
                 update_interval = VariablesMap["update_interval"].as<int>();
@@ -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<int>();
 
-            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<string> 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<string>();
+
                 int update_interval = 0;
                 if ( vm.count("update_interval") )
-                    update_interval = VariablesMap["update_interval"].as<int>();
+                    update_interval = vm["update_interval"].as<int>();
 
                 int max_updates_within_interval = 0;
                 if ( vm.count("max_updates_within_interval") )
-                    max_updates_within_interval = VariablesMap["max_updates_within_interval"].as<int>();
+                    max_updates_within_interval = vm["max_updates_within_interval"].as<int>();
 
                 int dns_cache_ttl = 0;
                 if ( vm.count("dns_cache_ttl") )
-                    dns_cache_ttl = VariablesMap["dns_cache_ttl"].as<int>();
+                    dns_cache_ttl = vm["dns_cache_ttl"].as<int>();
 
-                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);
index 712eb8b..9365340 100644 (file)
@@ -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);
 
index 6c6185a..f413b9a 100644 (file)
@@ -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);
+    }
+}
index 9a6fb43..61f7055 100644 (file)
@@ -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
index a7b9719..a45dca2 100644 (file)
@@ -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;
 
index a9486bc..e0ac01d 100644 (file)
@@ -136,8 +136,6 @@ list<string> 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;
 }
 
 
index fa9fcc1..74dafb4 100644 (file)
@@ -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;
 }
 
 
index ed43578..00e85fc 100644 (file)
@@ -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;
 }
 
 
index daf0584..ca19579 100644 (file)
@@ -183,8 +183,6 @@ list<string> 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 (file)
index 0000000..7109b6a
--- /dev/null
@@ -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 <time.h>
+#include <boost/foreach.hpp>
+#include <boost/regex.hpp>
+
+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<string,string> ServiceGnudip::parse_initial_request(const string& curl_data) const
+{
+    map<string,string> response;
+
+    // regex for salt
+    boost::regex expr_salt("<meta name=\"salt\" content=\"(.*)\">");
+    // regex for time
+    boost::regex expr_time("<meta name=\"time\" content=\"(.*)\">");
+    // regex for sign
+    boost::regex expr_sign("<meta name=\"sign\" content=\"(.*)\">");
+
+    boost::smatch matches;
+
+    // Get the salt out of received http data
+    if ( boost::regex_search(curl_data,matches,expr_salt) )
+    {
+        response.insert(pair<string,string>("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<string,string>("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<string,string>("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<string,string> 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<string,string>::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<class Archive>
+void ServiceGnudip::serialize(Archive & ar, const unsigned int version)
+{
+    ar & boost::serialization::base_object<Service>(*this);
+}
diff --git a/src/service_gnudip.h b/src/service_gnudip.h
new file mode 100644 (file)
index 0000000..8e6306f
--- /dev/null
@@ -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 <string>
+
+#include "service.h"
+#include "logger.h"
+
+#include <boost/serialization/array.hpp>
+#include <boost/shared_ptr.hpp>
+#include <list>
+#include <map>
+
+class ServiceGnudip : public Service
+{
+
+private:
+
+    friend class boost::serialization::access;
+    template<class Archive>
+    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<std::string,std::string> 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<ServiceGnudip> 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
index 9bd0e6a..31b7c57 100644 (file)
@@ -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;
 }
 
 
index c407526..47e5e8d 100644 (file)
@@ -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;
 }
 
 
index 54b3793..30e160a 100644 (file)
@@ -17,6 +17,7 @@
 #include "service_easydns.h"
 #include "service_tzo.h"
 #include "service_zoneedit.h"
+#include "service_gnudip.h"
 
 #include <boost/foreach.hpp>
 
@@ -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 (file)
index 0000000..1f10ce8
--- /dev/null
@@ -0,0 +1,58 @@
+/** @file
+ * @brief Util class implementation.
+ *
+ *
+ *
+ * @copyright Intra2net AG
+ * @license GPLv2
+*/
+
+#include "util.h"
+
+#include <stdio.h>
+#include <openssl/evp.h>
+#include <openssl/md5.h>
+
+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 (file)
index 0000000..43321de
--- /dev/null
@@ -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