Merge branch 'development' into LTS_development

# Conflicts:
#	src/controller/controller_api.cpp
This commit is contained in:
Thulinma 2018-03-20 14:56:49 +01:00
commit d3d93eb4da

View file

@ -20,6 +20,15 @@
#include "controller_license.h" #include "controller_license.h"
/*LTS-END*/ /*LTS-END*/
/// Returns the challenge string for authentication, given the socket connection.
std::string getChallenge(Socket::Connection & conn){
time_t Time = time(0);
tm * TimeInfo = localtime( &Time);
std::stringstream Date;
Date << TimeInfo->tm_mday << "-" << TimeInfo->tm_mon << "-" << TimeInfo->tm_year + 1900;
return Secure::md5(Date.str().c_str() + conn.getHost());
}
///\brief Checks an authorization request for a given user. ///\brief Checks an authorization request for a given user.
///\param Request The request to be parsed. ///\param Request The request to be parsed.
///\param Response The location to store the generated response. ///\param Response The location to store the generated response.
@ -65,16 +74,8 @@
/// Please note that this is NOT secure. At all. Never use this mechanism over a public network! /// Please note that this is NOT secure. At all. Never use this mechanism over a public network!
/// A status of `"ACC_MADE"` indicates the account was created successfully and can now be used to login as normal. /// A status of `"ACC_MADE"` indicates the account was created successfully and can now be used to login as normal.
bool Controller::authorize(JSON::Value & Request, JSON::Value & Response, Socket::Connection & conn){ bool Controller::authorize(JSON::Value & Request, JSON::Value & Response, Socket::Connection & conn){
#ifdef NOAUTH std::string Challenge = getChallenge(conn);
Response["authorize"]["status"] = "OK";
return true;
#endif
time_t Time = time(0);
tm * TimeInfo = localtime( &Time);
std::stringstream Date;
std::string retval; std::string retval;
Date << TimeInfo->tm_mday << "-" << TimeInfo->tm_mon << "-" << TimeInfo->tm_year + 1900;
std::string Challenge = Secure::md5(Date.str().c_str() + conn.getHost());
if (Request.isMember("authorize") && Request["authorize"]["username"].asString() != ""){ if (Request.isMember("authorize") && Request["authorize"]["username"].asString() != ""){
std::string UserID = Request["authorize"]["username"]; std::string UserID = Request["authorize"]["username"];
if (Storage["account"].isMember(UserID)){ if (Storage["account"].isMember(UserID)){
@ -114,17 +115,34 @@ int Controller::handleAPIConnection(Socket::Connection & conn){
//while connected and not past login attempt limit //while connected and not past login attempt limit
while (conn && logins < 4){ while (conn && logins < 4){
if ((conn.spool() || conn.Received().size()) && H.Read(conn)){ if ((conn.spool() || conn.Received().size()) && H.Read(conn)){
//Catch prometheus requests //Are we local and not forwarded? Instant-authorized.
if (Controller::prometheus.size()){ if (!authorized && !H.hasHeader("X-Real-IP") && conn.isLocal()){
if (H.url == "/"+Controller::prometheus){ MEDIUM_MSG("Local API access automatically authorized");
handlePrometheus(H, conn, PROMETHEUS_TEXT); authorized = true;
H.Clean(); }
continue; #ifdef NOAUTH
} //If auth is disabled, always allow access.
if (H.url == "/"+Controller::prometheus+".json"){ authorized = true;
handlePrometheus(H, conn, PROMETHEUS_JSON); #endif
H.Clean(); if (!authorized && H.hasHeader("Authorization")){
continue; std::string auth = H.GetHeader("Authorization");
if (auth.substr(0, 5) == "json "){
INFO_MSG("Checking auth header");
JSON::Value req;
req["authorize"] = JSON::fromString(auth.substr(5));
if (Storage["account"]){
tthread::lock_guard<tthread::mutex> guard(configMutex);
authorized = authorize(req, req, conn);
if (!authorized){
H.Clean();
H.body = "Please login first or provide a valid token authentication.";
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
H.SetHeader("WWW-Authenticate", "json "+req["authorize"].toString());
H.SendResponse("403", "Not authorized", conn);
H.Clean();
continue;
}
}
} }
} }
JSON::Value Response; JSON::Value Response;
@ -148,11 +166,6 @@ int Controller::handleAPIConnection(Socket::Connection & conn){
} }
{//lock the config mutex here - do not unlock until done processing {//lock the config mutex here - do not unlock until done processing
tthread::lock_guard<tthread::mutex> guard(configMutex); tthread::lock_guard<tthread::mutex> guard(configMutex);
//Are we local and not forwarded? Instant-authorized.
if (!authorized && !H.hasHeader("X-Real-IP") && conn.isLocal()){
MEDIUM_MSG("Local API access automatically authorized");
authorized = true;
}
//if already authorized, do not re-check for authorization //if already authorized, do not re-check for authorization
if (authorized && Storage["account"]){ if (authorized && Storage["account"]){
Response["authorize"]["status"] = "OK"; Response["authorize"]["status"] = "OK";