diff options
author | Lee Clagett <code@leeclagett.com> | 2016-12-30 01:47:57 -0500 |
---|---|---|
committer | Lee Clagett <code@leeclagett.com> | 2017-01-11 03:21:17 -0500 |
commit | d81cb0870442a919388df181d2134535bc6d1425 (patch) | |
tree | 8f6560acdf3d463fa087f0c55fc057b35ae9126e /contrib/epee/include | |
parent | Merge pull request #1542 (diff) | |
download | monero-d81cb0870442a919388df181d2134535bc6d1425.tar.xz |
Added (not yet enabled) HTTP client authentication
Diffstat (limited to 'contrib/epee/include')
-rw-r--r-- | contrib/epee/include/net/http_auth.h | 115 | ||||
-rw-r--r-- | contrib/epee/include/net/http_protocol_handler.h | 6 | ||||
-rw-r--r-- | contrib/epee/include/net/http_server_impl_base.h | 2 |
3 files changed, 101 insertions, 22 deletions
diff --git a/contrib/epee/include/net/http_auth.h b/contrib/epee/include/net/http_auth.h index 795d213d9..bdbfa7524 100644 --- a/contrib/epee/include/net/http_auth.h +++ b/contrib/epee/include/net/http_auth.h @@ -28,32 +28,35 @@ #pragma once #include <boost/optional/optional.hpp> +#include <boost/utility/string_ref.hpp> #include <cstdint> -#include "http_base.h" +#include <functional> #include <string> #include <utility> +#include "http_base.h" + namespace epee { namespace net_utils { namespace http { - //! Implements RFC 2617 digest auth. Digests from RFC 7616 can be added. - class http_auth + struct login { - public: - struct login - { - login() : username(), password() {} - login(std::string username_, std::string password_) - : username(std::move(username_)), password(std::move(password_)) - {} + login() : username(), password() {} + login(std::string username_, std::string password_) + : username(std::move(username_)), password(std::move(password_)) + {} - std::string username; - std::string password; - }; + std::string username; + std::string password; + }; + //! Implements RFC 2617 digest auth. Digests from RFC 7616 can be added. + class http_server_auth + { + public: struct session { session(login credentials_) @@ -65,21 +68,97 @@ namespace net_utils std::uint32_t counter; }; - http_auth() : user() {} - http_auth(login credentials); + http_server_auth() : user() {} + http_server_auth(login credentials); //! \return Auth response, or `boost::none` iff `request` had valid auth. boost::optional<http_response_info> get_response(const http_request_info& request) { if (user) + return do_get_response(request); + return boost::none; + } + private: + boost::optional<http_response_info> do_get_response(const http_request_info& request); + + boost::optional<session> user; + }; + + //! Implements RFC 2617 digest auth. Digests from RFC 7616 can be added. + class http_client_auth + { + public: + enum status : std::uint8_t { kSuccess = 0, kBadPassword, kParseFailure }; + + struct session + { + session(login credentials_) + : credentials(std::move(credentials_)), server(), counter(0) + {} + + struct keys { - return process(request); - } + using algorithm = + std::function<std::string(const session&, boost::string_ref, boost::string_ref)>; + + keys() : nonce(), opaque(), realm(), generator() {} + keys(std::string nonce_, std::string opaque_, std::string realm_, algorithm generator_) + : nonce(std::move(nonce_)) + , opaque(std::move(opaque_)) + , realm(std::move(realm_)) + , generator(std::move(generator_)) + {} + + std::string nonce; + std::string opaque; + std::string realm; + algorithm generator; + }; + + login credentials; + keys server; + std::uint32_t counter; + }; + + http_client_auth() : user() {} + http_client_auth(login credentials); + + /*! + Clients receiving a 401 response code from the server should call this + function to process the server auth. Then, before every client request, + `get_auth_field()` should be called to retrieve the newest + authorization request. + + \return `kBadPassword` if client will never be able to authenticate, + `kParseFailure` if all server authentication responses were invalid, + and `kSuccess` if `get_auth_field` is ready to generate authorization + fields. + */ + status handle_401(const http_response_info& response) + { + if (user) + return do_handle_401(response); + return kBadPassword; + } + + /*! + After calling `handle_401`, clients should call this function to + generate an authentication field for every request. + + \return A HTTP "Authorization" field if `handle_401(...)` previously + returned `kSuccess`. + */ + boost::optional<std::pair<std::string, std::string>> get_auth_field( + const boost::string_ref method, const boost::string_ref uri) + { + if (user) + return do_get_auth_field(method, uri); return boost::none; } private: - boost::optional<http_response_info> process(const http_request_info& request); + status do_handle_401(const http_response_info&); + boost::optional<std::pair<std::string, std::string>> do_get_auth_field(boost::string_ref, boost::string_ref); boost::optional<session> user; }; diff --git a/contrib/epee/include/net/http_protocol_handler.h b/contrib/epee/include/net/http_protocol_handler.h index 3813f9d7c..69ea04fbe 100644 --- a/contrib/epee/include/net/http_protocol_handler.h +++ b/contrib/epee/include/net/http_protocol_handler.h @@ -52,7 +52,7 @@ namespace net_utils { std::string m_folder; std::string m_required_user_agent; - boost::optional<http_auth::login> m_user; + boost::optional<login> m_user; critical_section m_lock; }; @@ -173,7 +173,7 @@ namespace net_utils : simple_http_connection_handler<t_connection_context>(psnd_hndlr, config), m_config(config), m_conn_context(conn_context), - m_auth(m_config.m_user ? http_auth{*m_config.m_user} : http_auth{}) + m_auth(m_config.m_user ? http_server_auth{*m_config.m_user} : http_server_auth{}) {} inline bool handle_request(const http_request_info& query_info, http_response_info& response) { @@ -214,7 +214,7 @@ namespace net_utils //simple_http_connection_handler::config_type m_stub_config; config_type& m_config; t_connection_context& m_conn_context; - http_auth m_auth; + http_server_auth m_auth; }; } } diff --git a/contrib/epee/include/net/http_server_impl_base.h b/contrib/epee/include/net/http_server_impl_base.h index f6b2d6941..a5cc1a917 100644 --- a/contrib/epee/include/net/http_server_impl_base.h +++ b/contrib/epee/include/net/http_server_impl_base.h @@ -53,7 +53,7 @@ namespace epee {} bool init(const std::string& bind_port = "0", const std::string& bind_ip = "0.0.0.0", - std::string user_agent = "", boost::optional<net_utils::http::http_auth::login> user = boost::none) + std::string user_agent = "", boost::optional<net_utils::http::login> user = boost::none) { //set self as callback handler |