Finish support for RPC user/pass auth.

This commit is contained in:
JoelKatz
2013-01-18 05:35:10 -08:00
parent fd76033e55
commit ae51e9d203
5 changed files with 23 additions and 13 deletions

View File

@@ -11,7 +11,7 @@ SETUP_LOG();
void HTTPRequest::reset() void HTTPRequest::reset()
{ {
vHeaders.clear(); mHeaders.clear();
sRequestBody.clear(); sRequestBody.clear();
sAuthorization.clear(); sAuthorization.clear();
iDataSize = 0; iDataSize = 0;
@@ -67,8 +67,6 @@ HTTPRequestAction HTTPRequest::consume(boost::asio::streambuf& buf)
eState = getting_body; eState = getting_body;
return haREAD_RAW; return haREAD_RAW;
} }
vHeaders.push_back(line);
size_t colon = line.find(':'); size_t colon = line.find(':');
if (colon != std::string::npos) if (colon != std::string::npos)
{ {
@@ -79,6 +77,8 @@ HTTPRequestAction HTTPRequest::consume(boost::asio::streambuf& buf)
std::string headerValue = line.substr(colon+1); std::string headerValue = line.substr(colon+1);
boost::trim(headerValue); boost::trim(headerValue);
mHeaders[headerName] += headerValue;
if (headerName == "connection") if (headerName == "connection")
{ {
boost::to_lower(headerValue); boost::to_lower(headerValue);

View File

@@ -2,7 +2,7 @@
#define HTTPREQUEST__HPP #define HTTPREQUEST__HPP
#include <string> #include <string>
#include <vector> #include <map>
#include <boost/asio/streambuf.hpp> #include <boost/asio/streambuf.hpp>
@@ -32,7 +32,7 @@ protected:
std::string sRequestBody; std::string sRequestBody;
std::string sAuthorization; std::string sAuthorization;
std::vector<std::string> vHeaders; std::map<std::string, std::string> mHeaders;
int iDataSize; int iDataSize;
bool bShouldClose; bool bShouldClose;
@@ -49,7 +49,7 @@ public:
std::string& peekAuth() { return sAuthorization; } std::string& peekAuth() { return sAuthorization; }
std::string getAuth() { return sAuthorization; } std::string getAuth() { return sAuthorization; }
std::vector<std::string>& peekHeaders() { return vHeaders; } std::map<std::string, std::string>& peekHeaders() { return mHeaders; }
std::string getReplyHeaders(bool forceClose); std::string getReplyHeaders(bool forceClose);
HTTPRequestAction consume(boost::asio::streambuf&); HTTPRequestAction consume(boost::asio::streambuf&);

View File

@@ -41,4 +41,6 @@ extern std::string JSONRPCReply(const Json::Value& result, const Json::Value& er
extern Json::Value JSONRPCError(int code, const std::string& message); extern Json::Value JSONRPCError(int code, const std::string& message);
extern bool HTTPAuthorized(const std::map<std::string, std::string>& mapHeaders);
#endif #endif

View File

@@ -47,7 +47,12 @@ void RPCServer::handle_read_req(const boost::system::error_code& e)
} }
req += strCopy(mQueryVec); req += strCopy(mQueryVec);
if (!HTTPAuthorized(mHTTPRequest.peekHeaders()))
mReplyStr = HTTPReply(403, "Forbidden");
else
mReplyStr = handleRequest(req); mReplyStr = handleRequest(req);
boost::asio::async_write(mSocket, boost::asio::buffer(mReplyStr), boost::asio::async_write(mSocket, boost::asio::buffer(mReplyStr),
boost::bind(&RPCServer::handle_write, shared_from_this(), boost::asio::placeholders::error)); boost::bind(&RPCServer::handle_write, shared_from_this(), boost::asio::placeholders::error));
} }
@@ -108,6 +113,7 @@ void RPCServer::handle_read_line(const boost::system::error_code& e)
std::string RPCServer::handleRequest(const std::string& requestStr) std::string RPCServer::handleRequest(const std::string& requestStr)
{ {
cLog(lsTRACE) << "handleRequest " << requestStr; cLog(lsTRACE) << "handleRequest " << requestStr;
Json::Value id; Json::Value id;
// Parse request // Parse request

View File

@@ -204,17 +204,19 @@ std::string DecodeBase64(std::string s)
return result; return result;
} }
bool HTTPAuthorized(std::map<std::string, std::string>& mapHeaders) bool HTTPAuthorized(const std::map<std::string, std::string>& mapHeaders)
{ // This is currently not used {
std::string strAuth = mapHeaders["authorization"]; std::map<std::string, std::string>::const_iterator it = mapHeaders.find("authorization");
if (strAuth.substr(0,6) != "Basic ") if ((it == mapHeaders.end()) || (it->second.substr(0,6) != "Basic "))
return theConfig.RPC_ADMIN_USER.empty() && theConfig.RPC_ADMIN_PASSWORD.empty(); return theConfig.RPC_USER.empty() && theConfig.RPC_PASSWORD.empty();
std::string strUserPass64 = strAuth.substr(6);
std::string strUserPass64 = it->second.substr(6);
boost::trim(strUserPass64); boost::trim(strUserPass64);
std::string strUserPass = DecodeBase64(strUserPass64); std::string strUserPass = DecodeBase64(strUserPass64);
std::string::size_type nColon = strUserPass.find(":"); std::string::size_type nColon = strUserPass.find(":");
if (nColon == std::string::npos) if (nColon == std::string::npos)
return false; return false;
std::string strUser = strUserPass.substr(0, nColon); std::string strUser = strUserPass.substr(0, nColon);
std::string strPassword = strUserPass.substr(nColon+1); std::string strPassword = strUserPass.substr(nColon+1);
return (strUser == theConfig.RPC_USER) && (strPassword == theConfig.RPC_PASSWORD); return (strUser == theConfig.RPC_USER) && (strPassword == theConfig.RPC_PASSWORD);