changeset 23:62bd05fe4b7c

support for ssl
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 28 Aug 2012 10:18:34 +0200
parents 1bc6327d1de3
children 166664f0f860
files CMakeLists.txt Core/HttpServer/MongooseServer.cpp Core/HttpServer/MongooseServer.h Core/Toolbox.cpp PalantirServer/PalantirInitialization.cpp PalantirServer/PalantirInitialization.h PalantirServer/main.cpp Resources/CMake/MongooseConfiguration.cmake Resources/Configuration.json
diffstat 9 files changed, 153 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Mon Aug 27 11:45:53 2012 +0200
+++ b/CMakeLists.txt	Tue Aug 28 10:18:34 2012 +0200
@@ -7,6 +7,7 @@
 
 SET(STATIC_BUILD ON CACHE BOOL "Static build of the third-party libraries (necessary for Windows)")
 SET(STANDALONE_BUILD OFF CACHE BOOL "Standalone build (necessary for cross-compilation or binary releases)")
+SET(ENABLE_SSL ON CACHE BOOL "Include support for SSL")
 
 if (${CMAKE_CROSSCOMPILING})
   SET(STANDALONE_BUILD ON)
--- a/Core/HttpServer/MongooseServer.cpp	Mon Aug 27 11:45:53 2012 +0200
+++ b/Core/HttpServer/MongooseServer.cpp	Tue Aug 28 10:18:34 2012 +0200
@@ -394,6 +394,22 @@
   }
 
 
+  static bool Authorize(MongooseServer& that,
+                        HttpOutput& output,
+                        struct mg_connection *connection,
+                        const struct mg_request_info *request)
+  {
+    /*std::string s = "HTTP/1.0 401 Unauthorized\r\n" 
+      "WWW-Authenticate: Digest realm=\"www.palanthir.com\",qop=\"auth\",nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\""
+      "\r\n\r\n";
+    output.Send(&s[0], s.size());
+
+    return false;*/
+
+    return true;
+  }
+
+
 
   static void* Callback(enum mg_event event,
                         struct mg_connection *connection,
@@ -413,6 +429,19 @@
         headers.insert(std::make_pair(name, request->http_headers[i].value));
       }
 
+      printf("=========================\n");
+      printf(" URI: [%s]\n", request->uri);
+      for (HttpHandler::Arguments::const_iterator i = headers.begin(); i != headers.end(); i++)
+      {
+        printf("[%s] = [%s]\n", i->first.c_str(), i->second.c_str());
+      }
+
+      // Authenticate this connection
+      if (!Authorize(*that, c, connection, request))
+      {
+        return (void*) "";
+      }
+
       std::string postData;
 
       if (!strcmp(request->request_method, "GET"))
@@ -501,6 +530,7 @@
   MongooseServer::MongooseServer() : pimpl_(new PImpl)
   {
     pimpl_->context_ = NULL;
+    ssl_ = false;
     port_ = 8000;
   }
 
@@ -524,8 +554,15 @@
     {
       std::string port = boost::lexical_cast<std::string>(port_);
 
+      if (ssl_)
+      {
+        port += "s";
+      }
+
       const char *options[] = {
         "listening_ports", port.c_str(), 
+        ssl_ ? "ssl_certificate" : NULL,
+        certificate_.c_str(),
         NULL
       };
 
@@ -566,4 +603,35 @@
     }
   }
 
+
+  void MongooseServer::RegisterUser(const char* username,
+                                    const char* password)
+  {
+    Stop();
+    registeredUsers_[username] = password;
+  }
+
+  void MongooseServer::SetSslEnabled(bool enabled)
+  {
+    Stop();
+
+#if PALANTIR_SSL_ENABLED == 0
+    if (enabled)
+    {
+      throw PalantirException("Palantir has been build without SSL support");
+    }
+    else
+    {
+      ssl_ = false;
+    }
+#else
+    ssl_ = enabled;
+#endif
+  }
+
+  void MongooseServer::SetSslCertificate(const char* path)
+  {
+    Stop();
+    certificate_ = path;
+  }
 }
--- a/Core/HttpServer/MongooseServer.h	Mon Aug 27 11:45:53 2012 +0200
+++ b/Core/HttpServer/MongooseServer.h	Tue Aug 28 10:18:34 2012 +0200
@@ -23,6 +23,7 @@
 #include "HttpHandler.h"
 
 #include <list>
+#include <map>
 #include <stdint.h>
 #include <boost/shared_ptr.hpp>
 
@@ -40,6 +41,11 @@
     typedef std::list<HttpHandler*> Handlers;
     Handlers handlers_;
 
+    typedef std::map<std::string, std::string> RegisteredUsers;
+    RegisteredUsers registeredUsers_;
+
+    bool ssl_;
+    std::string certificate_;
     uint16_t port_;
   
     bool IsRunning() const;
@@ -60,8 +66,25 @@
 
     void Stop();
 
+    void RegisterUser(const char* username,
+                      const char* password);
+
     void RegisterHandler(HttpHandler* handler);  // This takes the ownership
 
+    bool IsSslEnabled() const
+    {
+      return ssl_;
+    }
+
+    void SetSslEnabled(bool enabled);
+
+    const std::string& GetSslCertificate() const
+    {
+      return certificate_;
+    }
+
+    void SetSslCertificate(const char* path);
+
     void ClearHandlers();
 
     // Can return NULL if no handler is associated to this URI
--- a/Core/Toolbox.cpp	Mon Aug 27 11:45:53 2012 +0200
+++ b/Core/Toolbox.cpp	Tue Aug 28 10:18:34 2012 +0200
@@ -306,7 +306,6 @@
   }
 
 
-
   static char GetHexadecimalCharacter(uint8_t value)
   {
     assert(value < 16);
@@ -317,6 +316,7 @@
       return (value - 10) + 'a';
   }
 
+
   void Toolbox::ComputeMD5(std::string& result,
                            const std::string& data)
   {
@@ -338,6 +338,5 @@
       result[2 * i] = GetHexadecimalCharacter(actualHash[i] / 16);
       result[2 * i + 1] = GetHexadecimalCharacter(actualHash[i] % 16);
     }
-
   }
 }
--- a/PalantirServer/PalantirInitialization.cpp	Mon Aug 27 11:45:53 2012 +0200
+++ b/PalantirServer/PalantirInitialization.cpp	Tue Aug 28 10:18:34 2012 +0200
@@ -123,6 +123,22 @@
     }
   }
 
+  bool GetGlobalBoolParameter(const std::string& parameter,
+                              bool defaultValue)
+  {
+    boost::mutex::scoped_lock lock(globalMutex_);
+
+    if (configuration_->isMember(parameter))
+    {
+      return (*configuration_) [parameter].asBool();
+    }
+    else
+    {
+      return defaultValue;
+    }
+  }
+
+
 
 
   void GetDicomModality(const std::string& name,
--- a/PalantirServer/PalantirInitialization.h	Mon Aug 27 11:45:53 2012 +0200
+++ b/PalantirServer/PalantirInitialization.h	Tue Aug 28 10:18:34 2012 +0200
@@ -36,6 +36,9 @@
   int GetGlobalIntegerParameter(const std::string& parameter,
                                 int defaultValue);
 
+  bool GetGlobalBoolParameter(const std::string& parameter,
+                              bool defaultValue);
+
   void GetDicomModality(const std::string& name,
                         std::string& aet,
                         std::string& address,
--- a/PalantirServer/main.cpp	Mon Aug 27 11:45:53 2012 +0200
+++ b/PalantirServer/main.cpp	Tue Aug 28 10:18:34 2012 +0200
@@ -123,6 +123,17 @@
       MongooseServer httpServer;
       httpServer.SetPort(GetGlobalIntegerParameter("HttpPort", 8000));
 
+      if (GetGlobalBoolParameter("SslEnabled", false))
+      {
+        std::string certificate = GetGlobalStringParameter("SslCertificate", "certificate.pem");
+        httpServer.SetSslEnabled(true);
+        httpServer.SetSslCertificate(certificate.c_str());
+      }
+      else
+      {
+        httpServer.SetSslEnabled(false);
+      }
+
 #if PALANTIR_STANDALONE == 1
       httpServer.RegisterHandler(new EmbeddedResourceHttpHandler("/app", EmbeddedResources::PALANTIR_EXPLORER));
 #else
--- a/Resources/CMake/MongooseConfiguration.cmake	Mon Aug 27 11:45:53 2012 +0200
+++ b/Resources/CMake/MongooseConfiguration.cmake	Tue Aug 28 10:18:34 2012 +0200
@@ -15,9 +15,20 @@
   ${MONGOOSE_SOURCES_DIR}/mongoose.c
   )
 
-add_definitions(
-  # Remove SSL support from mongoose
-  -DNO_SSL=1
-  )
+if (${ENABLE_SSL})
+  add_definitions(
+    -DPALANTIR_SSL_ENABLED=1
+    )
+  if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
+    link_libraries(dl)
+  endif()
+
+else()
+  add_definitions(
+    -DPALANTIR_SSL_ENABLED=0
+    -DNO_SSL=1   # Remove SSL support from mongoose
+    )
+endif()
+
 
 source_group(ThirdParty\\Mongoose REGULAR_EXPRESSION ${MONGOOSE_SOURCES_DIR}/.*)
--- a/Resources/Configuration.json	Mon Aug 27 11:45:53 2012 +0200
+++ b/Resources/Configuration.json	Tue Aug 28 10:18:34 2012 +0200
@@ -1,12 +1,27 @@
 {
+    // Path to the directory that holds the database
     "StorageDirectory" : "PalantirStorage",
+
+    // HTTP port for the REST services and for the GUI
     "HttpPort" : 8000,
 
+    // The DICOM Application Entity Title
     "DicomAet" : "ANY-SCP",
+
+    // The DICOM port
     "DicomPort" : 4242,
+
+    // The list of the DICOM modalities.
     "DicomModalities" : {
+        // "sample" : [ "SAMPLESCP", "192.168.100.42", 104 ]
     },
 
+    // Whether or not SSL is enabled
+    "SslEnabled" : false,
+
+    // Path to the SSL certificate
+    "SslCertificate" : "certificate.pem",
+
     "PalantirPeers" : {
     }
 }