Browse Source

* HTTPServer.{cpp,h}: basic auth

pull/489/head
hagen 9 years ago
parent
commit
678650beaf
  1. 59
      HTTPServer.cpp
  2. 8
      HTTPServer.h

59
HTTPServer.cpp

@ -10,6 +10,7 @@
#include "Base.h" #include "Base.h"
#include "FS.h" #include "FS.h"
#include "Log.h" #include "Log.h"
#include "Config.h"
#include "Tunnel.h" #include "Tunnel.h"
#include "TransitTunnel.h" #include "TransitTunnel.h"
#include "Transports.h" #include "Transports.h"
@ -641,6 +642,15 @@ namespace http {
} }
} }
HTTPConnection::HTTPConnection (std::shared_ptr<boost::asio::ip::tcp::socket> socket):
m_Socket (socket), m_Timer (socket->get_io_service ()), m_BufferLen (0)
{
/* cache options */
i2p::config::GetOption("http.auth", needAuth);
i2p::config::GetOption("http.user", user);
i2p::config::GetOption("http.pass", pass);
};
void HTTPConnection::Receive () void HTTPConnection::Receive ()
{ {
m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE), m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE),
@ -672,6 +682,7 @@ namespace http {
} }
if (ret == 0) if (ret == 0)
return; /* need more data */ return; /* need more data */
HandleRequest (request); HandleRequest (request);
} }
@ -684,11 +695,44 @@ namespace http {
m_Socket->close (); m_Socket->close ();
} }
bool HTTPConnection::CheckAuth (const HTTPReq & req) {
/* method #1: http://user:pass@127.0.0.1:7070/ */
if (req.uri.find('@') != std::string::npos) {
URL url;
if (url.parse(req.uri) && url.user == user && url.pass == pass)
return true;
}
/* method #2: 'Authorization' header sent */
if (req.headers.count("Authorization") > 0) {
std::string provided = req.headers.find("Authorization")->second;
std::string expected = user + ":" + pass;
char b64_creds[64];
std::size_t len = 0;
len = i2p::data::ByteStreamToBase64((unsigned char *)expected.c_str(), expected.length(), b64_creds, sizeof(b64_creds));
b64_creds[len] = '\0';
expected = "Basic ";
expected += b64_creds;
if (provided == expected)
return true;
}
LogPrint(eLogWarning, "HTTPServer: auth failure from ", m_Socket->remote_endpoint().address ());
return false;
}
void HTTPConnection::HandleRequest (const HTTPReq & req) void HTTPConnection::HandleRequest (const HTTPReq & req)
{ {
std::stringstream s; std::stringstream s;
std::string content; std::string content;
HTTPRes res; HTTPRes res;
if (needAuth && !CheckAuth(req)) {
res.code = 401;
res.headers.insert(std::pair<std::string, std::string>("WWW-Authenticate", "Basic realm=\"WebAdmin\""));
SendReply(res, content);
return;
}
// Html5 head start // Html5 head start
ShowPageHead (s); ShowPageHead (s);
if (req.uri.find("page=") != std::string::npos) if (req.uri.find("page=") != std::string::npos)
@ -797,6 +841,21 @@ namespace http {
void HTTPServer::Start () void HTTPServer::Start ()
{ {
bool needAuth; i2p::config::GetOption("http.auth", needAuth);
std::string user; i2p::config::GetOption("http.user", user);
std::string pass; i2p::config::GetOption("http.pass", pass);
/* generate pass if needed */
if (needAuth && pass == "") {
char alnum[] = "0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
pass.resize(16);
for (size_t i = 0; i < pass.size(); i++) {
pass[i] = alnum[rand() % (sizeof(alnum) - 1)];
}
i2p::config::SetOption("http.pass", pass);
LogPrint(eLogInfo, "HTTPServer: password set to ", pass);
}
m_Thread = std::unique_ptr<std::thread>(new std::thread (std::bind (&HTTPServer::Run, this))); m_Thread = std::unique_ptr<std::thread>(new std::thread (std::bind (&HTTPServer::Run, this)));
m_Acceptor.listen (); m_Acceptor.listen ();
Accept (); Accept ();

8
HTTPServer.h

@ -11,9 +11,7 @@ namespace http {
{ {
public: public:
HTTPConnection (std::shared_ptr<boost::asio::ip::tcp::socket> socket): HTTPConnection (std::shared_ptr<boost::asio::ip::tcp::socket> socket);
m_Socket (socket), m_Timer (socket->get_io_service ()),
m_BufferLen (0) {};
void Receive (); void Receive ();
private: private:
@ -22,6 +20,7 @@ namespace http {
void Terminate (const boost::system::error_code& ecode); void Terminate (const boost::system::error_code& ecode);
void RunRequest (); void RunRequest ();
bool CheckAuth (const HTTPReq & req);
void HandleRequest (const HTTPReq & req); void HandleRequest (const HTTPReq & req);
void HandlePage (const HTTPReq & req, HTTPRes & res, std::stringstream& data); void HandlePage (const HTTPReq & req, HTTPRes & res, std::stringstream& data);
void HandleCommand (const HTTPReq & req, HTTPRes & res, std::stringstream& data); void HandleCommand (const HTTPReq & req, HTTPRes & res, std::stringstream& data);
@ -33,6 +32,9 @@ namespace http {
boost::asio::deadline_timer m_Timer; boost::asio::deadline_timer m_Timer;
char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1]; char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1];
size_t m_BufferLen; size_t m_BufferLen;
bool needAuth;
std::string user;
std::string pass;
}; };
class HTTPServer class HTTPServer

Loading…
Cancel
Save