Browse Source

Merge remote-tracking branch 'purple/openssl'

pull/628/head
Jeff Becker 8 years ago
parent
commit
4fb0eeda37
No known key found for this signature in database
GPG Key ID: AB950234D6EA286B
  1. 26
      HTTPServer.cpp
  2. 2
      Makefile.mingw
  3. 1
      NetDb.cpp
  4. 2
      UPnP.h
  5. 29
      Win32/Win32App.cpp
  6. 1
      Win32/Win32App.h
  7. 2
      docs/configuration.md
  8. 159
      util.cpp
  9. 29
      util.h

26
HTTPServer.cpp

@ -22,6 +22,9 @@
#include "HTTPServer.h" #include "HTTPServer.h"
#include "Daemon.h" #include "Daemon.h"
#include "util.h" #include "util.h"
#ifdef WIN32_APP
#include "Win32/Win32App.h"
#endif
// For image and info // For image and info
#include "version.h" #include "version.h"
@ -409,15 +412,21 @@ namespace http {
else else
s << " <a href=\"/?cmd=" << HTTP_COMMAND_ENABLE_TRANSIT << "\">Accept transit tunnels</a><br>\r\n"; s << " <a href=\"/?cmd=" << HTTP_COMMAND_ENABLE_TRANSIT << "\">Accept transit tunnels</a><br>\r\n";
#if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) #if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID))
if (Daemon.gracefullShutdownInterval) { if (Daemon.gracefullShutdownInterval)
{
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "\">Cancel gracefull shutdown ("; s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "\">Cancel gracefull shutdown (";
s << Daemon.gracefullShutdownInterval; s << Daemon.gracefullShutdownInterval;
s << " seconds remains)</a><br>\r\n"; s << " seconds remains)</a><br>\r\n";
} else { }
else
{
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "\">Start gracefull shutdown</a><br>\r\n"; s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "\">Start gracefull shutdown</a><br>\r\n";
} }
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "\">Force shutdown</a><br>\r\n";
#endif #endif
#ifdef WIN32_APP
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "\">Gracefull shutdown</a><br>\r\n";
#endif
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "\">Force shutdown</a><br>\r\n";
} }
void ShowTransitTunnels (std::stringstream& s) void ShowTransitTunnels (std::stringstream& s)
@ -723,6 +732,9 @@ namespace http {
i2p::context.SetAcceptsTunnels (false); i2p::context.SetAcceptsTunnels (false);
#if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) #if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID))
Daemon.gracefullShutdownInterval = 10*60; Daemon.gracefullShutdownInterval = 10*60;
#endif
#ifdef WIN32_APP
i2p::win32::GracefulShutdown ();
#endif #endif
} else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) { } else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) {
i2p::context.SetAcceptsTunnels (true); i2p::context.SetAcceptsTunnels (true);
@ -770,12 +782,14 @@ namespace http {
std::string pass; i2p::config::GetOption("http.pass", pass); std::string pass; i2p::config::GetOption("http.pass", pass);
/* generate pass if needed */ /* generate pass if needed */
if (needAuth && pass == "") { if (needAuth && pass == "") {
uint8_t random[16];
char alnum[] = "0123456789" char alnum[] = "0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"; "abcdefghijklmnopqrstuvwxyz";
pass.resize(16); pass.resize(sizeof(random));
for (size_t i = 0; i < pass.size(); i++) { RAND_bytes(random, sizeof(random));
pass[i] = alnum[rand() % (sizeof(alnum) - 1)]; for (size_t i = 0; i < sizeof(random); i++) {
pass[i] = alnum[random[i] % (sizeof(alnum) - 1)];
} }
i2p::config::SetOption("http.pass", pass); i2p::config::SetOption("http.pass", pass);
LogPrint(eLogInfo, "HTTPServer: password set to ", pass); LogPrint(eLogInfo, "HTTPServer: password set to ", pass);

2
Makefile.mingw

@ -37,7 +37,7 @@ ifeq ($(USE_WIN32_APP), yes)
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC)) DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
endif endif
ifeq ($(USE_AESNI),yes) ifeq ($(USE_AESNI),1)
CPU_FLAGS = -maes -DAESNI CPU_FLAGS = -maes -DAESNI
else else
CPU_FLAGS = -msse CPU_FLAGS = -msse

1
NetDb.cpp

@ -14,7 +14,6 @@
#include "RouterContext.h" #include "RouterContext.h"
#include "Garlic.h" #include "Garlic.h"
#include "NetDb.h" #include "NetDb.h"
#include "util.h"
using namespace i2p::transport; using namespace i2p::transport;

2
UPnP.h

@ -13,8 +13,6 @@
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include "util.h"
namespace i2p namespace i2p
{ {
namespace transport namespace transport

29
Win32/Win32App.cpp

@ -2,6 +2,7 @@
#include <windows.h> #include <windows.h>
#include <shellapi.h> #include <shellapi.h>
#include "../Config.h" #include "../Config.h"
#include "../RouterContext.h"
#include "../version.h" #include "../version.h"
#include "resource.h" #include "resource.h"
#include "Win32App.h" #include "Win32App.h"
@ -15,10 +16,13 @@
#define ID_EXIT 2001 #define ID_EXIT 2001
#define ID_CONSOLE 2002 #define ID_CONSOLE 2002
#define ID_APP 2003 #define ID_APP 2003
#define ID_GRACEFUL_SHUTDOWN 2004
#define ID_TRAY_ICON 2050 #define ID_TRAY_ICON 2050
#define WM_TRAYICON (WM_USER + 1) #define WM_TRAYICON (WM_USER + 1)
#define IDT_GRACEFUL_SHUTDOWN_TIMER 2100
namespace i2p namespace i2p
{ {
namespace win32 namespace win32
@ -30,6 +34,7 @@ namespace win32
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app"); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app");
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About..."); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, NULL, NULL); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, NULL, NULL);
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown");
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit"); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit");
SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE); SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE);
SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0); SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0);
@ -82,6 +87,7 @@ namespace win32
case WM_CLOSE: case WM_CLOSE:
{ {
RemoveTrayIcon (hWnd); RemoveTrayIcon (hWnd);
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
PostQuitMessage (0); PostQuitMessage (0);
break; break;
} }
@ -101,6 +107,12 @@ namespace win32
PostMessage (hWnd, WM_CLOSE, 0, 0); PostMessage (hWnd, WM_CLOSE, 0, 0);
return 0; return 0;
} }
case ID_GRACEFUL_SHUTDOWN:
{
i2p::context.SetAcceptsTunnels (false);
SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes
return 0;
}
case ID_CONSOLE: case ID_CONSOLE:
{ {
char buf[30]; char buf[30];
@ -167,6 +179,15 @@ namespace win32
} }
break; break;
} }
case WM_TIMER:
{
if (wParam == IDT_GRACEFUL_SHUTDOWN_TIMER)
{
PostMessage (hWnd, WM_CLOSE, 0, 0); // exit
return 0;
}
break;
}
} }
return DefWindowProc( hWnd, uMsg, wParam, lParam); return DefWindowProc( hWnd, uMsg, wParam, lParam);
} }
@ -218,5 +239,13 @@ namespace win32
{ {
UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL)); UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL));
} }
bool GracefulShutdown ()
{
HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"));
if (hWnd)
PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_GRACEFUL_SHUTDOWN, 0), 0);
return hWnd;
}
} }
} }

1
Win32/Win32App.h

@ -10,6 +10,7 @@ namespace win32
bool StartWin32App (); bool StartWin32App ();
void StopWin32App (); void StopWin32App ();
int RunWin32App (); int RunWin32App ();
bool GracefulShutdown ();
} }
} }
#endif // WIN32APP_H__ #endif // WIN32APP_H__

2
docs/configuration.md

@ -109,7 +109,7 @@ tunnels.conf:
# * keys -- our identity, if unset, will be generated on every startup, # * keys -- our identity, if unset, will be generated on every startup,
# if set and file missing, keys will be generated and placed to this file # if set and file missing, keys will be generated and placed to this file
# * address -- local interface to bind # * address -- local interface to bind
# * signaturetype -- signature type for new destination. 0,1 or 7 # * signaturetype -- signature type for new destination. 0 (DSA/SHA1), 1 (EcDSA/SHA256) or 7 (EdDSA/SHA512)
[IRC] [IRC]
type = client type = client
address = 127.0.0.1 address = 127.0.0.1

159
util.cpp

@ -1,12 +1,7 @@
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
#include <algorithm>
#include <cctype>
#include <functional>
#include <fstream>
#include <set>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>
#include "util.h" #include "util.h"
#include "Log.h" #include "Log.h"
@ -60,158 +55,6 @@ namespace i2p
{ {
namespace util namespace util
{ {
namespace http
{
std::string GetHttpContent (std::istream& response)
{
std::string version, statusMessage;
response >> version; // HTTP version
int status;
response >> status; // status
std::getline (response, statusMessage);
if (status == 200) // OK
{
bool isChunked = false;
std::string header;
while (!response.eof () && header != "\r")
{
std::getline(response, header);
auto colon = header.find (':');
if (colon != std::string::npos)
{
std::string field = header.substr (0, colon);
std::transform(field.begin(), field.end(), field.begin(), ::tolower);
if (field == i2p::util::http::TRANSFER_ENCODING)
isChunked = (header.find ("chunked", colon + 1) != std::string::npos);
}
}
std::stringstream ss;
if (isChunked)
MergeChunkedResponse (response, ss);
else
ss << response.rdbuf();
return ss.str();
}
else
{
LogPrint (eLogError, "HTTPClient: error, server responds ", status);
return "";
}
}
void MergeChunkedResponse (std::istream& response, std::ostream& merged)
{
while (!response.eof ())
{
std::string hexLen;
size_t len;
std::getline (response, hexLen);
std::istringstream iss (hexLen);
iss >> std::hex >> len;
if (!len || len > 10000000L) // 10M
{
LogPrint (eLogError, "Unexpected chunk length ", len);
break;
}
char * buf = new char[len];
response.read (buf, len);
merged.write (buf, len);
delete[] buf;
std::getline (response, hexLen); // read \r\n after chunk
}
}
url::url(const std::string& url_s)
{
portstr_ = "80";
port_ = 80;
user_ = "";
pass_ = "";
parse(url_s);
}
// code for parser tests
//{
// i2p::util::http::url u_0("http://127.0.0.1:7070/asdasd?qqqqqqqqqqqq");
// i2p::util::http::url u_1("http://user:password@site.com:8080/asdasd?qqqqqqqqqqqqq");
// i2p::util::http::url u_2("http://user:password@site.com/asdasd?qqqqqqqqqqqqqq");
// i2p::util::http::url u_3("http://user:@site.com/asdasd?qqqqqqqqqqqqq");
// i2p::util::http::url u_4("http://user@site.com/asdasd?qqqqqqqqqqqq");
// i2p::util::http::url u_5("http://@site.com:800/asdasd?qqqqqqqqqqqq");
// i2p::util::http::url u_6("http://@site.com:err_port/asdasd?qqqqqqqqqqqq");
// i2p::util::http::url u_7("http://user:password@site.com:err_port/asdasd?qqqqqqqqqqqq");
//}
void url::parse(const std::string& url_s)
{
const std::string prot_end("://");
std::string::const_iterator prot_i = search(url_s.begin(), url_s.end(),
prot_end.begin(), prot_end.end());
protocol_.reserve(distance(url_s.begin(), prot_i));
transform(url_s.begin(), prot_i,
back_inserter(protocol_),
std::ptr_fun<int,int>(tolower)); // protocol is icase
if( prot_i == url_s.end() )
return;
advance(prot_i, prot_end.length());
std::string::const_iterator path_i = find(prot_i, url_s.end(), '/');
host_.reserve(distance(prot_i, path_i));
transform(prot_i, path_i,
back_inserter(host_),
std::ptr_fun<int,int>(tolower)); // host is icase
// parse user/password
auto user_pass_i = find(host_.begin(), host_.end(), '@');
if (user_pass_i != host_.end())
{
std::string user_pass = std::string(host_.begin(), user_pass_i);
auto pass_i = find(user_pass.begin(), user_pass.end(), ':');
if (pass_i != user_pass.end())
{
user_ = std::string(user_pass.begin(), pass_i);
pass_ = std::string(pass_i + 1, user_pass.end());
}
else
user_ = user_pass;
host_.assign(user_pass_i + 1, host_.end());
}
// parse port
auto port_i = find(host_.begin(), host_.end(), ':');
if (port_i != host_.end())
{
portstr_ = std::string(port_i + 1, host_.end());
host_.assign(host_.begin(), port_i);
try{
port_ = boost::lexical_cast<decltype(port_)>(portstr_);
}
catch (std::exception e) {
port_ = 80;
}
}
std::string::const_iterator query_i = find(path_i, url_s.end(), '?');
path_.assign(path_i, query_i);
if( query_i != url_s.end() )
++query_i;
query_.assign(query_i, url_s.end());
}
std::string urlDecode(const std::string& data)
{
std::string res(data);
for (size_t pos = res.find('%'); pos != std::string::npos; pos = res.find('%',pos+1))
{
char c = strtol(res.substr(pos+1,2).c_str(), NULL, 16);
res.replace(pos,3,1,c);
}
return res;
}
}
namespace net namespace net
{ {
#ifdef WIN32 #ifdef WIN32

29
util.h

@ -22,7 +22,6 @@ namespace i2p
{ {
namespace util namespace util
{ {
/** /**
wrapper arround boost::lexical_cast that "never" fails wrapper arround boost::lexical_cast that "never" fails
*/ */
@ -35,34 +34,6 @@ namespace util
} }
} }
namespace http
{
// in (lower case)
const char ETAG[] = "etag"; // ETag
const char LAST_MODIFIED[] = "last-modified"; // Last-Modified
const char TRANSFER_ENCODING[] = "transfer-encoding"; // Transfer-Encoding
const char CONTENT_ENCODING[] = "content-encoding"; // Content-Encoding
// out
const char IF_NONE_MATCH[] = "If-None-Match";
const char IF_MODIFIED_SINCE[] = "If-Modified-Since";
std::string GetHttpContent (std::istream& response);
void MergeChunkedResponse (std::istream& response, std::ostream& merged);
std::string urlDecode(const std::string& data);
struct url {
url(const std::string& url_s); // omitted copy, ==, accessors, ...
private:
void parse(const std::string& url_s);
public:
std::string protocol_, host_, path_, query_;
std::string portstr_;
unsigned int port_;
std::string user_;
std::string pass_;
};
}
namespace net namespace net
{ {
int GetMTU (const boost::asio::ip::address& localAddress); int GetMTU (const boost::asio::ip::address& localAddress);

Loading…
Cancel
Save