Added error handling in Util::compute_md5_digest and avoided using of C functions...
authorBjoern Sikora <bjoern.sikora@intra2net.com>
Wed, 9 Sep 2009 12:55:11 +0000 (14:55 +0200)
committerBjoern Sikora <bjoern.sikora@intra2net.com>
Wed, 9 Sep 2009 12:55:11 +0000 (14:55 +0200)
src/logger.cpp
src/logger.h
src/service_gnudip.cpp
src/util.cpp
src/util.h

index f413b9a..f265eae 100644 (file)
@@ -1420,6 +1420,10 @@ void Logger::print_could_not_get_initial_gnudip_data() const
 }
 
 
+
+/**
+ * Gnudip protocol requires explicit declaration of a servername.
+ */
 void Logger::print_gnudip_requires_servername() const
 {
     int level = 0;
@@ -1430,3 +1434,19 @@ void Logger::print_gnudip_requires_servername() const
         log_warning(msg.str(),level);
     }
 }
+
+
+/**
+ * An exception occured while computing the md5 sum.
+ * @param what The exception occured.
+ */
+void Logger::print_exception_md5_sum(const std::string& what) const
+{
+    int level = 0;
+    if ( (level <= Loglevel) || ((level <= ExternalWarningLevel) && (!ExternalWarningLog.empty())) )
+    {
+        ostringstream msg;
+        msg << "An exception occured while computing a md5 sum: " << what << endl;
+        log_error(msg.str(),level);
+    }
+}
index 61f7055..7d85cdb 100644 (file)
@@ -207,6 +207,8 @@ public:
     void print_could_not_get_initial_gnudip_data() const;
 
     void print_gnudip_requires_servername() const;
+
+    void print_exception_md5_sum(const std::string& what) const;
 };
 
 #endif
index 7109b6a..fe5064a 100644 (file)
@@ -227,12 +227,31 @@ int ServiceGnudip::perform_update(const std::string& ip)
             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());
+        string pw_md5_hex;
+        try
+        {
+            pw_md5_hex = Util::compute_md5_digest(get_password());
+        }
+        catch ( invalid_argument e )
+        {
+            get_logger()->print_exception_md5_sum(e.what());
+            return -1;
+        }
 
         // 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);
+
+        string secret;
+        try
+        {
+            secret = Util::compute_md5_digest(pw_md5_hex);
+        }
+        catch ( invalid_argument e )
+        {
+            get_logger()->print_exception_md5_sum(e.what());
+            return -1;
+        }
 
         // Now its time to issue the second http_get operation
         string url = assemble_update_url(salt, time, sign, secret, ip);
index 1f10ce8..d2078d7 100644 (file)
@@ -1,5 +1,5 @@
 /** @file
- * @brief Util class implementation.
+ * @brief Util namespace implementation.
  *
  *
  *
@@ -9,50 +9,67 @@
 
 #include "util.h"
 
-#include <stdio.h>
+#include <sstream>
 #include <openssl/evp.h>
-#include <openssl/md5.h>
 
-Util::Util()
-{
-}
-
-Util::~Util()
-{
-}
+using namespace std;
 
 /**
  * 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)
+string Util::compute_md5_digest(string data) throw (invalid_argument)
 {
     // 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;
+    unsigned int md_len = 0;
 
+    // Add all digest algorithms to the internal table.
     OpenSSL_add_all_digests();
 
+    // Get the md5 digest algorithm from the internal table.
     md = EVP_get_digestbyname("md5");
 
+    // Test if md is initialized.
+    if ( (md == NULL) || (EVP_MD_size(md) == 0) )
+        throw invalid_argument("NULL pointer: md");
+
+    // Initalize digest content mdctx.
     EVP_MD_CTX_init(&mdctx);
+
+    // Now we can call init_ex.
     EVP_DigestInit_ex(&mdctx, md, NULL);
-    EVP_DigestUpdate(&mdctx, data.c_str(), strlen(data.c_str()));
+
+    // Test if data is empty.
+    if ( data.empty() )
+        throw invalid_argument("Passed data is empty");
+
+    // Hash the data. At this point data is not empty and &mdctx is initialized.
+    EVP_DigestUpdate(&mdctx, data.c_str(), data.size());
+
+    // Retrieve the digest value from &mdctx and place it in md_value.
     EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
-    EVP_MD_CTX_cleanup(&mdctx);
 
-    char buffer[2];
+    // Test if md_value is filled correctly and md_len is not zero.
+    if ( (md_len == 0) || (md_value == NULL) || (EVP_MD_CTX_size(&mdctx) == 0) )
+        throw invalid_argument("Retrieved invalid digest value");
+
+    // Internal cleanup of the digest content.
+    EVP_MD_CTX_cleanup(&mdctx);
+    EVP_cleanup();
 
-    for(int i = 0; i < md_len; i++)
+    // Convert md5 digest C string to hex.
+    ostringstream oss_digest_md5_hex;
+    for(unsigned int i = 0; i < md_len; ++i)
     {
-        sprintf(buffer,"%02x", md_value[i]);
-        result.append(buffer);
+        // We have to do a static cast to an decimal representation, cause otherwise ostringstream would interpret
+        // the stream as a character and output the character representation of the hex value.
+        oss_digest_md5_hex << hex << static_cast<unsigned short>(md_value[i]);
     }
 
-    return result;
+    return oss_digest_md5_hex.str();
 }
index 43321de..b7cb9fc 100644 (file)
@@ -1,5 +1,5 @@
 /** @file
- * @brief Util class header.
+ * @brief Util namespace header.
  *
  *
  *
 #define UTIL_H
 
 
-class Util
+namespace Util
 {
-private:
-
-
-public:
-
-    Util();
-
-    ~Util();
-
-    static std::string compute_md5_digest(std::string);
-
+    static std::string compute_md5_digest(std::string) throw (std::invalid_argument);
 };
 
 #endif