# HG changeset patch # User Sebastien Jodogne # Date 1346318541 -7200 # Node ID 96e57b863dd9dbeab2af872d474ebc220b1ec23e # Parent 0c3e317f35e851f9ea43684ff66bbd45127588db option to disallow remote access diff -r 0c3e317f35e8 -r 96e57b863dd9 Core/HttpServer/MongooseServer.cpp --- a/Core/HttpServer/MongooseServer.cpp Thu Aug 30 09:35:38 2012 +0200 +++ b/Core/HttpServer/MongooseServer.cpp Thu Aug 30 11:22:21 2012 +0200 @@ -38,6 +38,8 @@ #define PALANTIR_REALM "Palantir Secure Area" +static const long LOCALHOST = (127ll << 24) + 1ll; + namespace Palantir { @@ -397,6 +399,15 @@ } + static void SendUnauthorized(HttpOutput& output) + { + std::string s = "HTTP/1.1 401 Unauthorized\r\n" + "WWW-Authenticate: Basic realm=\"" PALANTIR_REALM "\"" + "\r\n\r\n"; + output.Send(&s[0], s.size()); + } + + static bool Authorize(const MongooseServer& that, const HttpHandler::Arguments& headers, HttpOutput& output) @@ -416,10 +427,7 @@ if (!granted) { - std::string s = "HTTP/1.1 401 Unauthorized\r\n" - "WWW-Authenticate: Basic realm=\"" PALANTIR_REALM "\"" - "\r\n\r\n"; - output.Send(&s[0], s.size()); + SendUnauthorized(output); return false; } else @@ -437,9 +445,16 @@ if (event == MG_NEW_REQUEST) { MongooseServer* that = (MongooseServer*) (request->user_data); + MongooseOutput output(connection); + + if (!that->IsRemoteAccessAllowed() && + request->remote_ip != LOCALHOST) + { + SendUnauthorized(output); + return (void*) ""; + } HttpHandler::Arguments arguments, headers; - MongooseOutput c(connection); for (int i = 0; i < request->num_headers; i++) { @@ -450,7 +465,7 @@ // Authenticate this connection if (that->IsAuthenticationEnabled() && - !Authorize(*that, headers, c)) + !Authorize(*that, headers, output)) { return (void*) ""; } @@ -466,7 +481,7 @@ HttpHandler::Arguments::const_iterator ct = headers.find("content-type"); if (ct == headers.end()) { - c.SendHeader(HttpStatus_400_BadRequest); + output.SendHeader(HttpStatus_400_BadRequest); return (void*) ""; } @@ -486,15 +501,15 @@ switch (status) { case PostDataStatus_NoLength: - c.SendHeader(HttpStatus_411_LengthRequired); + output.SendHeader(HttpStatus_411_LengthRequired); return (void*) ""; case PostDataStatus_Failure: - c.SendHeader(HttpStatus_400_BadRequest); + output.SendHeader(HttpStatus_400_BadRequest); return (void*) ""; case PostDataStatus_Pending: - c.AnswerBuffer(""); + output.AnswerBuffer(""); return (void*) ""; default: @@ -510,18 +525,18 @@ { try { - handler->Handle(c, std::string(request->request_method), + handler->Handle(output, std::string(request->request_method), uri, headers, arguments, postData); } catch (PalantirException& e) { std::cerr << "MongooseServer Exception [" << e.What() << "]" << std::endl; - c.SendHeader(HttpStatus_500_InternalServerError); + output.SendHeader(HttpStatus_500_InternalServerError); } } else { - c.SendHeader(HttpStatus_404_NotFound); + output.SendHeader(HttpStatus_404_NotFound); } // Mark as processed @@ -543,6 +558,7 @@ MongooseServer::MongooseServer() : pimpl_(new PImpl) { pimpl_->context_ = NULL; + remoteAllowed_ = false; authentication_ = false; ssl_ = false; port_ = 8000; @@ -664,6 +680,13 @@ certificate_ = path; } + void MongooseServer::SetRemoteAccessAllowed(bool allowed) + { + Stop(); + remoteAllowed_ = allowed; + } + + bool MongooseServer::IsValidBasicHttpAuthentication(const std::string& basic) const { return registeredUsers_.find(basic) != registeredUsers_.end(); diff -r 0c3e317f35e8 -r 96e57b863dd9 Core/HttpServer/MongooseServer.h --- a/Core/HttpServer/MongooseServer.h Thu Aug 30 09:35:38 2012 +0200 +++ b/Core/HttpServer/MongooseServer.h Thu Aug 30 11:22:21 2012 +0200 @@ -44,6 +44,7 @@ typedef std::set RegisteredUsers; RegisteredUsers registeredUsers_; + bool remoteAllowed_; bool authentication_; bool ssl_; std::string certificate_; @@ -95,6 +96,13 @@ void SetSslCertificate(const char* path); + bool IsRemoteAccessAllowed() const + { + return remoteAllowed_; + } + + void SetRemoteAccessAllowed(bool allowed); + void ClearHandlers(); // Can return NULL if no handler is associated to this URI diff -r 0c3e317f35e8 -r 96e57b863dd9 PalantirServer/DicomIntegerPixelAccessor.cpp --- a/PalantirServer/DicomIntegerPixelAccessor.cpp Thu Aug 30 09:35:38 2012 +0200 +++ b/PalantirServer/DicomIntegerPixelAccessor.cpp Thu Aug 30 11:22:21 2012 +0200 @@ -80,8 +80,8 @@ throw PalantirException(ErrorCode_NotImplemented); } - printf("%d %d %d %d %d %d %d\n", width_, height_, samplesPerPixel_, bitsAllocated, - bitsStored, highBit, pixelRepresentation); + /*printf("%d %d %d %d %d %d %d\n", width_, height_, samplesPerPixel_, bitsAllocated, + bitsStored, highBit, pixelRepresentation);*/ bytesPerPixel_ = bitsAllocated / 8; shift_ = highBit + 1 - bitsStored; diff -r 0c3e317f35e8 -r 96e57b863dd9 PalantirServer/PalantirRestApi.cpp --- a/PalantirServer/PalantirRestApi.cpp Thu Aug 30 09:35:38 2012 +0200 +++ b/PalantirServer/PalantirRestApi.cpp Thu Aug 30 11:22:21 2012 +0200 @@ -49,7 +49,7 @@ } is.setEos(); - printf("[%d]\n", postData.size()); + //printf("[%d]\n", postData.size()); DcmFileFormat dicomFile; if (dicomFile.read(is).good()) @@ -467,7 +467,8 @@ else if (uri.size() == 3 && uri[0] == "instances" && (uri[2] == "file" || - uri[2] == "all-tags")) + uri[2] == "tags" || + uri[2] == "named-tags")) { std::string fileUuid, contentType; if (uri[2] == "file") @@ -475,7 +476,8 @@ existingResource = index_.GetDicomFile(fileUuid, uri[1]); contentType = "application/dicom"; } - else + else if (uri[2] == "tags" || + uri[2] == "named-tags") { existingResource = index_.GetJsonFile(fileUuid, uri[1]); contentType = "application/json"; diff -r 0c3e317f35e8 -r 96e57b863dd9 PalantirServer/main.cpp --- a/PalantirServer/main.cpp Thu Aug 30 09:35:38 2012 +0200 +++ b/PalantirServer/main.cpp Thu Aug 30 11:22:21 2012 +0200 @@ -49,14 +49,14 @@ virtual void Handle(const std::vector& dicomFile, const DicomMap& dicomSummary, const Json::Value& dicomJson, - const std::string& distantAet) + const std::string& remoteAet) { std::string instanceUuid; if (dicomFile.size() > 0) { index_.Store(instanceUuid, storage_, reinterpret_cast(&dicomFile[0]), dicomFile.size(), - dicomSummary, dicomJson, distantAet); + dicomSummary, dicomJson, remoteAet); } } }; @@ -121,6 +121,7 @@ // HTTP server MongooseServer httpServer; httpServer.SetPort(GetGlobalIntegerParameter("HttpPort", 8000)); + httpServer.SetRemoteAccessAllowed(GetGlobalBoolParameter("RemoteAccessAllowed", false)); httpServer.SetAuthenticationEnabled(GetGlobalBoolParameter("AuthenticationEnabled", false)); SetupRegisteredUsers(httpServer); diff -r 0c3e317f35e8 -r 96e57b863dd9 Resources/Configuration.json --- a/Resources/Configuration.json Thu Aug 30 09:35:38 2012 +0200 +++ b/Resources/Configuration.json Thu Aug 30 11:22:21 2012 +0200 @@ -33,6 +33,9 @@ * Security-related options **/ + // Whether remote hosts can connect to the HTTP server + "RemoteAccessAllowed" : false, + // Whether or not SSL is enabled "SslEnabled" : false, @@ -40,7 +43,7 @@ "SslCertificate" : "certificate.pem", // Whether or not the password protection is enabled - "AuthenticationEnabled" : true, + "AuthenticationEnabled" : false, // The list of the registered users. Because Palantir uses HTTP // Basic Authentication, the passwords are stored as plain text.