Skip to content

Commit

Permalink
[wip] inital HTTPS enablement for webserver
Browse files Browse the repository at this point in the history
  • Loading branch information
wsnipex committed Jul 17, 2015
1 parent 0d912d5 commit 375ad2c
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 4 deletions.
79 changes: 75 additions & 4 deletions xbmc/network/WebServer.cpp
Expand Up @@ -28,11 +28,13 @@
#include <memory>
#include <algorithm>
#include <stdexcept>
#include <fstream>

#include "URL.h"
#include "Util.h"
#include "XBDateTime.h"
#include "filesystem/File.h"
#include "filesystem/SpecialProtocol.h"
#include "network/httprequesthandler/IHTTPRequestHandler.h"
#include "settings/Settings.h"
#include "threads/SingleLock.h"
Expand Down Expand Up @@ -91,7 +93,9 @@ CWebServer::CWebServer()
m_daemon_ip4(NULL),
m_running(false),
m_needcredentials(false),
m_Credentials64Encoded("eGJtYzp4Ym1j") // xbmc:xbmc
m_Credentials64Encoded("eGJtYzp4Ym1j") /* xbmc:xbmc */,
m_key(),
m_cert()

{ }

Expand Down Expand Up @@ -1096,6 +1100,34 @@ static void logFromMHD(void* unused, const char* fmt, va_list ap)
}
}

bool CWebServer::LoadCert(std::string &skey, std::string &scert)
{
std::string keyFile = "special://userdata/server.key";
std::string certFile = "special://userdata/server.pem";
std::ifstream keyStr(CSpecialProtocol::TranslatePath(keyFile));
std::ifstream certStr(CSpecialProtocol::TranslatePath(certFile));
XFILE::CFile file;

if (!file.Exists(keyFile))
return false;
if (!file.Exists(certFile))
return false;

// slurp server encryption key and certificate
std::string keyPem( (std::istreambuf_iterator<char>(keyStr) ), (std::istreambuf_iterator<char>() ) );
std::string certPem( (std::istreambuf_iterator<char>(certStr) ), (std::istreambuf_iterator<char>() ) );
skey = keyPem;
scert = certPem;


if (skey.size() > 0 && scert.size() > 0)
{
CLog::Log(LOGERROR, "WebServer %s: found server key: %s, certificate: %s, HTTPS support enabled", __FUNCTION__, keyFile.c_str(), certFile.c_str());
return true;
}
return false;
}

struct MHD_Daemon* CWebServer::StartMHD(unsigned int flags, int port)
{
unsigned int timeout = 60 * 60 * 24;
Expand All @@ -1104,6 +1136,44 @@ struct MHD_Daemon* CWebServer::StartMHD(unsigned int flags, int port)
MHD_set_panic_func(&panicHandlerForMHD, NULL);
#endif

if (LoadCert(m_key, m_cert) && MHD_is_feature_supported(MHD_FEATURE_SSL) == MHD_YES)
// SSL enabled
return MHD_start_daemon(flags |
#if (MHD_VERSION >= 0x00040002) && (MHD_VERSION < 0x00090B01)
// use main thread for each connection, can only handle one request at a
// time [unless you set the thread pool size]
MHD_USE_SELECT_INTERNALLY
#else
// one thread per connection
// WARNING: set MHD_OPTION_CONNECTION_TIMEOUT to something higher than 1
// otherwise on libmicrohttpd 0.4.4-1 it spins a busy loop
MHD_USE_THREAD_PER_CONNECTION
#endif
#if (MHD_VERSION >= 0x00040001)
| MHD_USE_DEBUG /* Print MHD error messages to log */
#endif
| MHD_USE_SSL
,
port,
NULL,
NULL,
&CWebServer::AnswerToConnection,
this,

#if (MHD_VERSION >= 0x00040002) && (MHD_VERSION < 0x00090B01)
MHD_OPTION_THREAD_POOL_SIZE, 4,
#endif
MHD_OPTION_CONNECTION_LIMIT, 512,
MHD_OPTION_CONNECTION_TIMEOUT, timeout,
MHD_OPTION_URI_LOG_CALLBACK, &CWebServer::UriRequestLogger, this,
#if (MHD_VERSION >= 0x00040001)
MHD_OPTION_EXTERNAL_LOGGER, &logFromMHD, NULL,
#endif // MHD_VERSION >= 0x00040001
MHD_OPTION_HTTPS_MEM_KEY, m_key.c_str(),
MHD_OPTION_HTTPS_MEM_CERT, m_cert.c_str(),
MHD_OPTION_END);

// No SSL
return MHD_start_daemon(flags |
#if (MHD_VERSION >= 0x00040002) && (MHD_VERSION < 0x00090B01)
// use main thread for each connection, can only handle one request at a
Expand All @@ -1117,7 +1187,7 @@ struct MHD_Daemon* CWebServer::StartMHD(unsigned int flags, int port)
#endif
#if (MHD_VERSION >= 0x00040001)
| MHD_USE_DEBUG /* Print MHD error messages to log */
#endif
#endif
,
port,
NULL,
Expand All @@ -1139,6 +1209,8 @@ struct MHD_Daemon* CWebServer::StartMHD(unsigned int flags, int port)

bool CWebServer::Start(int port, const string &username, const string &password)
{
unsigned int flags = 0;

SetCredentials(username, password);
if (!m_running)
{
Expand All @@ -1148,9 +1220,8 @@ bool CWebServer::Start(int port, const string &username, const string &password)
closesocket(v6testSock);
m_daemon_ip6 = StartMHD(MHD_USE_IPv6, port);
}

m_daemon_ip4 = StartMHD(0, port);

m_running = (m_daemon_ip6 != NULL) || (m_daemon_ip4 != NULL);
if (m_running)
CLog::Log(LOGNOTICE, "WebServer: Started the webserver");
Expand Down
4 changes: 4 additions & 0 deletions xbmc/network/WebServer.h
Expand Up @@ -117,11 +117,15 @@ class CWebServer : public JSONRPC::ITransportLayer
static int AddHeader(struct MHD_Response *response, const std::string &name, const std::string &value);
static bool GetLastModifiedDateTime(XFILE::CFile *file, CDateTime &lastModified);

bool LoadCert(std::string &skey, std::string &scert);

struct MHD_Daemon *m_daemon_ip6;
struct MHD_Daemon *m_daemon_ip4;
bool m_running;
bool m_needcredentials;
std::string m_Credentials64Encoded;
std::string m_key;
std::string m_cert;
CCriticalSection m_critSection;
static std::vector<IHTTPRequestHandler *> m_requestHandlers;
};
Expand Down

0 comments on commit 375ad2c

Please sign in to comment.