aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2016-09-07 21:38:41 +0100
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2016-09-18 20:32:02 +0100
commiteeb2bbc0fcc9c5afa2c3aa12915b4d3f31115e56 (patch)
treec55799576b49814203891a6688ec2dbdf86b7bcf /contrib
parentMerge pull request #1099 (diff)
downloadmonero-eeb2bbc0fcc9c5afa2c3aa12915b4d3f31115e56.tar.xz
epee: optionally restrict HTTP service to a configurable user agent
This is intended to catch traffic coming from a web browser, so we avoid issues with a web page sending a transfer RPC to the wallet. Requiring a particular user agent can act as a simple password scheme, while we wait for 0MQ and proper authentication to be merged.
Diffstat (limited to 'contrib')
-rw-r--r--contrib/epee/include/net/http_base.h2
-rw-r--r--contrib/epee/include/net/http_client.h12
-rw-r--r--contrib/epee/include/net/http_protocol_handler.h1
-rw-r--r--contrib/epee/include/net/http_protocol_handler.inl23
-rw-r--r--contrib/epee/include/net/http_server_impl_base.h5
5 files changed, 31 insertions, 12 deletions
diff --git a/contrib/epee/include/net/http_base.h b/contrib/epee/include/net/http_base.h
index 2a227cc70..4ff74fe27 100644
--- a/contrib/epee/include/net/http_base.h
+++ b/contrib/epee/include/net/http_base.h
@@ -98,6 +98,7 @@ namespace net_utils
std::string m_content_encoding; //"Content-Encoding:"
std::string m_host; //"Host:"
std::string m_cookie; //"Cookie:"
+ std::string m_user_agent; //"User-Agent:"
fields_list m_etc_fields;
void clear()
@@ -110,6 +111,7 @@ namespace net_utils
m_content_encoding.clear();
m_host.clear();
m_cookie.clear();
+ m_user_agent.clear();
m_etc_fields.clear();
}
};
diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h
index 077c80230..3e8143738 100644
--- a/contrib/epee/include/net/http_client.h
+++ b/contrib/epee/include/net/http_client.h
@@ -638,10 +638,10 @@ using namespace std;
LOG_FRAME("http_stream_filter::parse_cached_header(*)", LOG_LEVEL_4);
STATIC_REGEXP_EXPR_1(rexp_mach_field,
- "\n?((Connection)|(Referer)|(Content-Length)|(Content-Type)|(Transfer-Encoding)|(Content-Encoding)|(Host)|(Cookie)"
- // 12 3 4 5 6 7 8 9
+ "\n?((Connection)|(Referer)|(Content-Length)|(Content-Type)|(Transfer-Encoding)|(Content-Encoding)|(Host)|(Cookie)|(User-Agent)"
+ // 12 3 4 5 6 7 8 9 10
"|([\\w-]+?)) ?: ?((.*?)(\r?\n))[^\t ]",
- //10 1112 13
+ //11 1213 14
boost::regex::icase | boost::regex::normal);
boost::smatch result;
@@ -653,8 +653,8 @@ using namespace std;
//lookup all fields and fill well-known fields
while( boost::regex_search( it_current_bound, it_end_bound, result, rexp_mach_field, boost::match_default) && result[0].matched)
{
- const size_t field_val = 12;
- //const size_t field_etc_name = 10;
+ const size_t field_val = 13;
+ //const size_t field_etc_name = 11;
int i = 2; //start position = 2
if(result[i++].matched)//"Connection"
@@ -675,6 +675,8 @@ using namespace std;
}
else if(result[i++].matched)//"Cookie"
body_info.m_cookie = result[field_val];
+ else if(result[i++].matched)//"User-Agent"
+ body_info.m_user_agent = result[field_val];
else if(result[i++].matched)//e.t.c (HAVE TO BE MATCHED!)
{;}
else
diff --git a/contrib/epee/include/net/http_protocol_handler.h b/contrib/epee/include/net/http_protocol_handler.h
index aed909778..40e3392db 100644
--- a/contrib/epee/include/net/http_protocol_handler.h
+++ b/contrib/epee/include/net/http_protocol_handler.h
@@ -49,6 +49,7 @@ namespace net_utils
struct http_server_config
{
std::string m_folder;
+ std::string m_required_user_agent;
critical_section m_lock;
};
diff --git a/contrib/epee/include/net/http_protocol_handler.inl b/contrib/epee/include/net/http_protocol_handler.inl
index 2458af047..6beff0109 100644
--- a/contrib/epee/include/net/http_protocol_handler.inl
+++ b/contrib/epee/include/net/http_protocol_handler.inl
@@ -285,7 +285,8 @@ namespace net_utils
}
break;
}
- analize_cached_request_header_and_invoke_state(pos);
+ if (!analize_cached_request_header_and_invoke_state(pos))
+ return false;
break;
}
case http_state_retriving_body:
@@ -387,8 +388,16 @@ namespace net_utils
{
LOG_ERROR("simple_http_connection_handler<t_connection_context>::analize_cached_request_header_and_invoke_state(): failed to anilize request header: " << m_cache);
m_state = http_state_error;
+ return false;
}
+ if (!m_config.m_required_user_agent.empty() && m_query_info.m_header_info.m_user_agent != m_config.m_required_user_agent)
+ {
+ LOG_ERROR("simple_http_connection_handler<t_connection_context>::analize_cached_request_header_and_invoke_state(): unexpected user agent: " << m_query_info.m_header_info.m_user_agent);
+ m_state = http_state_error;
+ return false;
+ }
+
m_cache.erase(0, pos);
std::string req_command_str = m_query_info.m_full_request_str;
@@ -473,10 +482,10 @@ namespace net_utils
LOG_FRAME("http_stream_filter::parse_cached_header(*)", LOG_LEVEL_3);
STATIC_REGEXP_EXPR_1(rexp_mach_field,
- "\n?((Connection)|(Referer)|(Content-Length)|(Content-Type)|(Transfer-Encoding)|(Content-Encoding)|(Host)|(Cookie)"
- // 12 3 4 5 6 7 8 9
+ "\n?((Connection)|(Referer)|(Content-Length)|(Content-Type)|(Transfer-Encoding)|(Content-Encoding)|(Host)|(Cookie)|(User-Agent)"
+ // 12 3 4 5 6 7 8 9 10
"|([\\w-]+?)) ?: ?((.*?)(\r?\n))[^\t ]",
- //10 1112 13
+ //11 1213 14
boost::regex::icase | boost::regex::normal);
boost::smatch result;
@@ -488,8 +497,8 @@ namespace net_utils
//lookup all fields and fill well-known fields
while( boost::regex_search( it_current_bound, it_end_bound, result, rexp_mach_field, boost::match_default) && result[0].matched)
{
- const size_t field_val = 12;
- const size_t field_etc_name = 10;
+ const size_t field_val = 13;
+ const size_t field_etc_name = 11;
int i = 2; //start position = 2
if(result[i++].matched)//"Connection"
@@ -508,6 +517,8 @@ namespace net_utils
body_info.m_host = result[field_val];
else if(result[i++].matched)//"Cookie"
body_info.m_cookie = result[field_val];
+ else if(result[i++].matched)//"User-Agent"
+ body_info.m_user_agent = result[field_val];
else if(result[i++].matched)//e.t.c (HAVE TO BE MATCHED!)
body_info.m_etc_fields.push_back(std::pair<std::string, std::string>(result[field_etc_name], result[field_val]));
else
diff --git a/contrib/epee/include/net/http_server_impl_base.h b/contrib/epee/include/net/http_server_impl_base.h
index 10f74b9a8..65fe5eed6 100644
--- a/contrib/epee/include/net/http_server_impl_base.h
+++ b/contrib/epee/include/net/http_server_impl_base.h
@@ -52,7 +52,7 @@ namespace epee
: m_net_server(external_io_service)
{}
- bool init(const std::string& bind_port = "0", const std::string& bind_ip = "0.0.0.0")
+ bool init(const std::string& bind_port = "0", const std::string& bind_ip = "0.0.0.0", const std::string &user_agent = "")
{
//set self as callback handler
@@ -61,6 +61,9 @@ namespace epee
//here set folder for hosting reqests
m_net_server.get_config_object().m_folder = "";
+ // workaround till we get auth/encryption
+ m_net_server.get_config_object().m_required_user_agent = user_agent;
+
LOG_PRINT_L0("Binding on " << bind_ip << ":" << bind_port);
bool res = m_net_server.init_server(bind_port, bind_ip);
if(!res)