aboutsummaryrefslogtreecommitdiff
path: root/contrib/epee/include/net/http_auth.h
diff options
context:
space:
mode:
authorLee Clagett <code@leeclagett.com>2016-12-30 01:47:57 -0500
committerLee Clagett <code@leeclagett.com>2017-01-11 03:21:17 -0500
commitd81cb0870442a919388df181d2134535bc6d1425 (patch)
tree8f6560acdf3d463fa087f0c55fc057b35ae9126e /contrib/epee/include/net/http_auth.h
parentMerge pull request #1542 (diff)
downloadmonero-d81cb0870442a919388df181d2134535bc6d1425.tar.xz
Added (not yet enabled) HTTP client authentication
Diffstat (limited to 'contrib/epee/include/net/http_auth.h')
-rw-r--r--contrib/epee/include/net/http_auth.h115
1 files changed, 97 insertions, 18 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;
};