@ -321,7 +321,7 @@ namespace proxy {
if ( ! m_Addresshelper )
if ( ! m_Addresshelper )
{
{
LogPrint ( eLogWarning , " HTTPProxy: Addresshelper request rejected " ) ;
LogPrint ( eLogWarning , " HTTPProxy: Addresshelper request rejected " ) ;
GenericProxyError ( tr ( " Invalid request " ) , tr ( " a ddresshelper is not supported" ) ) ;
GenericProxyError ( tr ( " Invalid request " ) , tr ( " A ddresshelper is not supported" ) ) ;
return true ;
return true ;
}
}
@ -341,28 +341,22 @@ namespace proxy {
}
}
if ( m_RequestURL . host ! = referer_url . host )
if ( m_RequestURL . host ! = referer_url . host )
{
{
// Attempt to forced overwriting by link with "&update=true" from harmful URL
if ( m_Confirm ) // Attempt to forced overwriting by link with "&update=true" from harmful URL
if ( m_Confirm )
{
{
LogPrint ( eLogWarning , " HTTPProxy: Address update from addresshelper rejected for " , m_RequestURL . host , " (referer is " , m_RequestURL . host . empty ( ) ? " empty " : " harmful " , " ) " ) ;
LogPrint ( eLogWarning , " HTTPProxy: Address update from addresshelper rejected for " , m_RequestURL . host , " (referer is " , m_RequestURL . host . empty ( ) ? " empty " : " harmful " , " ) " ) ;
std : : string full_url = m_RequestURL . to_string ( ) ;
std : : string full_url = m_RequestURL . to_string ( ) ;
std : : stringstream ss ;
std : : stringstream ss ;
ss < < tr ( " Host " ) < < " " < < m_RequestURL . host < < " <font color=red> " < < tr ( " already in router's addressbook " ) < < " </font>. " ;
ss < < tr ( " Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href= \" %s%s%s&update=true \" >Continue</a>. " ,
ss < < " <b> " < < tr ( /* Trying to overwrite an existing domain in the address book by direct link with "&update=true" is seems like an attack */ " Be careful: source of this URL may be harmful " ) < < " !</b> " ;
m_RequestURL . host , full_url , ( full_url . find ( ' ? ' ) ! = std : : string : : npos ? " &i2paddresshelper= " : " ?i2paddresshelper= " ) , jump ) ;
ss < < tr ( /* tr: The "record" means addressbook's record. That message appears when domain was already added to addressbook, but helper link is opened for it. */ " Click here to update record: " ) ;
ss < < " <a href= \" " < < full_url < < ( full_url . find ( ' ? ' ) ! = std : : string : : npos ? " &i2paddresshelper= " : " ?i2paddresshelper= " ) ;
ss < < jump < < " &update=true \" > " < < tr ( " Continue " ) < < " </a>. " ;
GenericProxyInfo ( tr ( " Addresshelper forced update rejected " ) , ss . str ( ) ) ;
GenericProxyInfo ( tr ( " Addresshelper forced update rejected " ) , ss . str ( ) ) ;
}
}
// Preventing unauthorized additions to the address book
else // Preventing unauthorized additions to the address book
else
{
{
LogPrint ( eLogDebug , " HTTPProxy: Adding address from addresshelper for " , m_RequestURL . host , " (generate refer-base page) " ) ;
LogPrint ( eLogDebug , " HTTPProxy: Adding address from addresshelper for " , m_RequestURL . host , " (generate refer-base page) " ) ;
std : : string full_url = m_RequestURL . to_string ( ) ;
std : : string full_url = m_RequestURL . to_string ( ) ;
std : : stringstream ss ;
std : : stringstream ss ;
ss < < tr ( " To add host " /*... in router's addressbook, click here */ ) < < " <b> " < < m_RequestURL . host < < " </b> " < < tr ( /* To add host SOMESHORT.i2p ... */ " in router's addressbook, click here " ) < < " : " ;
ss < < tr ( " To add host <b>%s</b> in router's addressbook, click here: <a href= \" %s%s%s \" >Continue</a>. " ,
ss < < " <a href= \" " < < full_url < < ( full_url . find ( ' ? ' ) ! = std : : string : : npos ? " &i2paddresshelper= " : " ?i2paddresshelper= " ) ;
m_RequestURL . host , full_url , ( full_url . find ( ' ? ' ) ! = std : : string : : npos ? " &i2paddresshelper= " : " ?i2paddresshelper= " ) , jump ) ;
ss < < jump < < " \" > " < < tr ( " Continue " ) < < " </a>. " ;
GenericProxyInfo ( tr ( " Addresshelper request " ) , ss . str ( ) ) ;
GenericProxyInfo ( tr ( " Addresshelper request " ) , ss . str ( ) ) ;
}
}
return true ; /* request processed */
return true ; /* request processed */
@ -372,8 +366,7 @@ namespace proxy {
LogPrint ( eLogInfo , " HTTPProxy: Added address from addresshelper for " , m_RequestURL . host ) ;
LogPrint ( eLogInfo , " HTTPProxy: Added address from addresshelper for " , m_RequestURL . host ) ;
std : : string full_url = m_RequestURL . to_string ( ) ;
std : : string full_url = m_RequestURL . to_string ( ) ;
std : : stringstream ss ;
std : : stringstream ss ;
ss < < tr ( " Host " ) < < " " < < m_RequestURL . host < < " " < < tr ( " added to router's addressbook from helper " ) < < " . " ;
ss < < tr ( " Host %s added to router's addressbook from helper. Click here to proceed: <a href= \" %s \" >Continue</a>. " , m_RequestURL . host , full_url ) ;
ss < < tr ( " Click here to proceed: " ) < < " <a href= \" " < < full_url < < " \" > " < < tr ( " Continue " ) < < " </a>. " ;
GenericProxyInfo ( tr ( " Addresshelper adding " ) , ss . str ( ) ) ;
GenericProxyInfo ( tr ( " Addresshelper adding " ) , ss . str ( ) ) ;
return true ; /* request processed */
return true ; /* request processed */
}
}
@ -381,10 +374,8 @@ namespace proxy {
{
{
std : : string full_url = m_RequestURL . to_string ( ) ;
std : : string full_url = m_RequestURL . to_string ( ) ;
std : : stringstream ss ;
std : : stringstream ss ;
ss < < tr ( " Host " ) < < " " < < m_RequestURL . host < < " <font color=red> " < < tr ( " already in router's addressbook " ) < < " </font>. " ;
ss < < tr ( " Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href= \" %s%s%s&update=true \" >Continue</a>. " ,
ss < < tr ( /* tr: The "record" means addressbook's record. That message appears when domain was already added to addressbook, but helper link is opened for it. */ " Click here to update record: " ) ;
m_RequestURL . host , full_url , ( full_url . find ( ' ? ' ) ! = std : : string : : npos ? " &i2paddresshelper= " : " ?i2paddresshelper= " ) , jump ) ;
ss < < " <a href= \" " < < full_url < < ( full_url . find ( ' ? ' ) ! = std : : string : : npos ? " &i2paddresshelper= " : " ?i2paddresshelper= " ) ;
ss < < jump < < " &update=true \" > " < < tr ( " Continue " ) < < " </a>. " ;
GenericProxyInfo ( tr ( " Addresshelper update " ) , ss . str ( ) ) ;
GenericProxyInfo ( tr ( " Addresshelper update " ) , ss . str ( ) ) ;
return true ; /* request processed */
return true ; /* request processed */
}
}
@ -398,7 +389,7 @@ namespace proxy {
auto pos = uri . find ( " : " ) ;
auto pos = uri . find ( " : " ) ;
if ( pos = = std : : string : : npos | | pos = = uri . size ( ) - 1 )
if ( pos = = std : : string : : npos | | pos = = uri . size ( ) - 1 )
{
{
GenericProxyError ( tr ( " Invalid request " ) , tr ( " invalid request uri " ) ) ;
GenericProxyError ( tr ( " Invalid request " ) , tr ( " Invalid request URI " ) ) ;
return true ;
return true ;
}
}
else
else
@ -458,10 +449,10 @@ namespace proxy {
if ( m_ProxyURL . parse ( m_OutproxyUrl ) )
if ( m_ProxyURL . parse ( m_OutproxyUrl ) )
ForwardToUpstreamProxy ( ) ;
ForwardToUpstreamProxy ( ) ;
else
else
GenericProxyError ( tr ( " Outproxy failure " ) , tr ( " b ad outproxy settings" ) ) ;
GenericProxyError ( tr ( " Outproxy failure " ) , tr ( " B ad outproxy settings" ) ) ;
} else {
} else {
LogPrint ( eLogWarning , " HTTPProxy: Outproxy failure for " , dest_host , " : no outproxy enabled " ) ;
LogPrint ( eLogWarning , " HTTPProxy: Outproxy failure for " , dest_host , " : no outproxy enabled " ) ;
std : : stringstream ss ; ss < < tr ( " Host " ) < < " " < < dest_host < < " " < < tr ( " not inside I2P network, but outproxy is not enabled " ) ;
std : : stringstream ss ; ss < < tr ( " Host %s is not inside I2P network, but outproxy is not enabled " , dest_host ) ;
GenericProxyError ( tr ( " Outproxy failure " ) , ss . str ( ) ) ;
GenericProxyError ( tr ( " Outproxy failure " ) , ss . str ( ) ) ;
}
}
return true ;
return true ;
@ -550,13 +541,13 @@ namespace proxy {
else
else
{
{
/* unknown type, complain */
/* unknown type, complain */
GenericProxyError ( tr ( " unknown outproxy url " ) , m_ProxyURL . to_string ( ) ) ;
GenericProxyError ( tr ( " Unknown outproxy URL " ) , m_ProxyURL . to_string ( ) ) ;
}
}
}
}
void HTTPReqHandler : : HandleUpstreamProxyResolved ( const boost : : system : : error_code & ec , boost : : asio : : ip : : tcp : : resolver : : iterator it , ProxyResolvedHandler handler )
void HTTPReqHandler : : HandleUpstreamProxyResolved ( const boost : : system : : error_code & ec , boost : : asio : : ip : : tcp : : resolver : : iterator it , ProxyResolvedHandler handler )
{
{
if ( ec ) GenericProxyError ( tr ( " c annot resolve upstream proxy" ) , ec . message ( ) ) ;
if ( ec ) GenericProxyError ( tr ( " C annot resolve upstream proxy" ) , ec . message ( ) ) ;
else handler ( * it ) ;
else handler ( * it ) ;
}
}
@ -564,7 +555,7 @@ namespace proxy {
{
{
if ( ! ec ) {
if ( ! ec ) {
if ( m_RequestURL . host . size ( ) > 255 ) {
if ( m_RequestURL . host . size ( ) > 255 ) {
GenericProxyError ( tr ( " hostname too long" ) , m_RequestURL . host ) ;
GenericProxyError ( tr ( " Hostname is too long" ) , m_RequestURL . host ) ;
return ;
return ;
}
}
uint16_t port = m_RequestURL . port ;
uint16_t port = m_RequestURL . port ;
@ -591,13 +582,13 @@ namespace proxy {
reqsize + = host . size ( ) ;
reqsize + = host . size ( ) ;
m_socks_buf [ + + reqsize ] = 0 ;
m_socks_buf [ + + reqsize ] = 0 ;
boost : : asio : : async_write ( * m_proxysock , boost : : asio : : buffer ( m_socks_buf , reqsize ) , boost : : asio : : transfer_all ( ) , std : : bind ( & HTTPReqHandler : : HandleSocksProxySendHandshake , this , std : : placeholders : : _1 , std : : placeholders : : _2 ) ) ;
boost : : asio : : async_write ( * m_proxysock , boost : : asio : : buffer ( m_socks_buf , reqsize ) , boost : : asio : : transfer_all ( ) , std : : bind ( & HTTPReqHandler : : HandleSocksProxySendHandshake , this , std : : placeholders : : _1 , std : : placeholders : : _2 ) ) ;
} else GenericProxyError ( tr ( " cannot connect to upstream socks proxy" ) , ec . message ( ) ) ;
} else GenericProxyError ( tr ( " Cannot connect to upstream SOCKS proxy" ) , ec . message ( ) ) ;
}
}
void HTTPReqHandler : : HandleSocksProxySendHandshake ( const boost : : system : : error_code & ec , std : : size_t bytes_transferred )
void HTTPReqHandler : : HandleSocksProxySendHandshake ( const boost : : system : : error_code & ec , std : : size_t bytes_transferred )
{
{
LogPrint ( eLogDebug , " HTTPProxy: Upstream SOCKS handshake sent " ) ;
LogPrint ( eLogDebug , " HTTPProxy: Upstream SOCKS handshake sent " ) ;
if ( ec ) GenericProxyError ( tr ( " Cannot negotiate with socks proxy " ) , ec . message ( ) ) ;
if ( ec ) GenericProxyError ( tr ( " Cannot negotiate with SOCKS proxy " ) , ec . message ( ) ) ;
else m_proxysock - > async_read_some ( boost : : asio : : buffer ( m_socks_buf , 8 ) , std : : bind ( & HTTPReqHandler : : HandleSocksProxyReply , this , std : : placeholders : : _1 , std : : placeholders : : _2 ) ) ;
else m_proxysock - > async_read_some ( boost : : asio : : buffer ( m_socks_buf , 8 ) , std : : bind ( & HTTPReqHandler : : HandleSocksProxyReply , this , std : : placeholders : : _1 , std : : placeholders : : _2 ) ) ;
}
}
@ -639,7 +630,7 @@ namespace proxy {
}
}
else
else
{
{
GenericProxyError ( tr ( " CONNECT error " ) , tr ( " Failed to C onnect " ) ) ;
GenericProxyError ( tr ( " CONNECT error " ) , tr ( " Failed to c onnect " ) ) ;
}
}
}
}
@ -650,7 +641,7 @@ namespace proxy {
m_send_buf = m_ClientResponse . to_string ( ) ;
m_send_buf = m_ClientResponse . to_string ( ) ;
boost : : asio : : async_write ( * m_sock , boost : : asio : : buffer ( m_send_buf ) , boost : : asio : : transfer_all ( ) , [ & ] ( const boost : : system : : error_code & ec , std : : size_t transferred )
boost : : asio : : async_write ( * m_sock , boost : : asio : : buffer ( m_send_buf ) , boost : : asio : : transfer_all ( ) , [ & ] ( const boost : : system : : error_code & ec , std : : size_t transferred )
{
{
if ( ec ) GenericProxyError ( tr ( " socks proxy error" ) , ec . message ( ) ) ;
if ( ec ) GenericProxyError ( tr ( " SOCKS proxy error" ) , ec . message ( ) ) ;
else HandoverToUpstreamProxy ( ) ;
else HandoverToUpstreamProxy ( ) ;
} ) ;
} ) ;
} else {
} else {
@ -658,7 +649,7 @@ namespace proxy {
LogPrint ( eLogDebug , " HTTPProxy: Send " , m_send_buf . size ( ) , " bytes " ) ;
LogPrint ( eLogDebug , " HTTPProxy: Send " , m_send_buf . size ( ) , " bytes " ) ;
boost : : asio : : async_write ( * m_proxysock , boost : : asio : : buffer ( m_send_buf ) , boost : : asio : : transfer_all ( ) , [ & ] ( const boost : : system : : error_code & ec , std : : size_t transferred )
boost : : asio : : async_write ( * m_proxysock , boost : : asio : : buffer ( m_send_buf ) , boost : : asio : : transfer_all ( ) , [ & ] ( const boost : : system : : error_code & ec , std : : size_t transferred )
{
{
if ( ec ) GenericProxyError ( tr ( " f ailed to send request to upstream" ) , ec . message ( ) ) ;
if ( ec ) GenericProxyError ( tr ( " F ailed to send request to upstream" ) , ec . message ( ) ) ;
else HandoverToUpstreamProxy ( ) ;
else HandoverToUpstreamProxy ( ) ;
} ) ;
} ) ;
}
}
@ -676,18 +667,18 @@ namespace proxy {
ss < < " error code: " ;
ss < < " error code: " ;
ss < < ( int ) m_socks_buf [ 1 ] ;
ss < < ( int ) m_socks_buf [ 1 ] ;
std : : string msg = ss . str ( ) ;
std : : string msg = ss . str ( ) ;
GenericProxyError ( tr ( " socks proxy error" ) , msg ) ;
GenericProxyError ( tr ( " SOCKS proxy error" ) , msg ) ;
}
}
}
}
else GenericProxyError ( tr ( " No Reply From socks proxy " ) , ec . message ( ) ) ;
else GenericProxyError ( tr ( " No reply from SOCKS proxy " ) , ec . message ( ) ) ;
}
}
void HTTPReqHandler : : HandleUpstreamHTTPProxyConnect ( const boost : : system : : error_code & ec )
void HTTPReqHandler : : HandleUpstreamHTTPProxyConnect ( const boost : : system : : error_code & ec )
{
{
if ( ! ec ) {
if ( ! ec ) {
LogPrint ( eLogDebug , " HTTPProxy: Connected to http upstream " ) ;
LogPrint ( eLogDebug , " HTTPProxy: Connected to http upstream " ) ;
GenericProxyError ( tr ( " c annot connect" ) , tr ( " http out proxy not implemented" ) ) ;
GenericProxyError ( tr ( " C annot connect" ) , tr ( " HTTP out proxy not implemented" ) ) ;
} else GenericProxyError ( tr ( " cannot connect to upstream http proxy" ) , ec . message ( ) ) ;
} else GenericProxyError ( tr ( " Cannot connect to upstream HTTP proxy" ) , ec . message ( ) ) ;
}
}
/* will be called after some data received from client */
/* will be called after some data received from client */