diff options
author | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2016-09-07 21:38:41 +0100 |
---|---|---|
committer | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2016-09-18 20:32:02 +0100 |
commit | eeb2bbc0fcc9c5afa2c3aa12915b4d3f31115e56 (patch) | |
tree | c55799576b49814203891a6688ec2dbdf86b7bcf /contrib/epee/include/net | |
parent | Merge pull request #1099 (diff) | |
download | monero-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/epee/include/net')
-rw-r--r-- | contrib/epee/include/net/http_base.h | 2 | ||||
-rw-r--r-- | contrib/epee/include/net/http_client.h | 12 | ||||
-rw-r--r-- | contrib/epee/include/net/http_protocol_handler.h | 1 | ||||
-rw-r--r-- | contrib/epee/include/net/http_protocol_handler.inl | 23 | ||||
-rw-r--r-- | contrib/epee/include/net/http_server_impl_base.h | 5 |
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) |