Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow user to provide an alternative Authentication mechanism #458

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 92 additions & 14 deletions include/amqpcpp/login.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,28 +39,79 @@ class Login
*/
std::string _password;

/**
* The security mechanism
* @var string
*/
std::string _mechanism;

/**
* The security response
* @var string
*/
std::string _response;


public:
/**
* Default constructor
* Default constructor with PLAIN authentication
*/
Login() : _user("guest"), _password("guest") {}
Login() : _user("guest"), _password("guest")
{
// Set default PLAIN mechanism and response
_mechanism = "PLAIN";
_response = saslPlain();
}

/**
* Constructor
* Constructor with PLAIN authentication mechanism
*
* @param user
* @param password
*/
Login(std::string user, std::string password) :
_user(std::move(user)), _password(std::move(password)) {}
_user(std::move(user)), _password(std::move(password))
{
// Set default PLAIN mechanism and response
_mechanism = "PLAIN";
_response = saslPlain();
}

/**
* Constructor
* Constructor with PLAIN authentication mechanism
* @param user
* @param password
*/
Login(const char *user, const char *password) :
_user(user), _password(password) {}
_user(user), _password(password)
{
// Set default PLAIN mechanism and response
_mechanism = "PLAIN";
_response = saslPlain();
}

/**
* Constructor with custom authentication mechanism
* @param user
* @param password
* @param mechanism
* @param response
*/
Login(std::string user, std::string password, std::string mechanism, std::string response)
: _user(std::move(user))
, _password(std::move(password))
, _mechanism(std::move(mechanism))
, _response(std::move(response)) {}

/**
* Constructor with custom authentication mechanism
* @param user
* @param password
* @param mechanism
* @param response
*/
Login(const char *user, const char *password, const char *mechanism, const char *response)
: _user(user), _password(password), _mechanism(mechanism), _response(response) {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add more in-code documentation? I don't understand the use case where it is up to the caller to supply a username, password, mechanism and response. What sort of values is one supposed to pass here?

Login mylogin("my-username", "my-password", "my-special-login-mechanism", "bla bla bla");

Is this permitted?


/**
* Destructor
Expand All @@ -73,7 +124,7 @@ class Login
*/
operator bool () const
{
return !_user.empty() || !_password.empty();
return !_user.empty() || !_password.empty() || !_mechanism.empty() || !_response.empty();
}

/**
Expand All @@ -82,7 +133,7 @@ class Login
*/
bool operator! () const
{
return _user.empty() && _password.empty();
return _user.empty() && _password.empty() && _mechanism.empty() && _response.empty();
}

/**
Expand All @@ -103,6 +154,24 @@ class Login
return _password;
}

/**
* Retrieve the security mechanism
* @return string
*/
const std::string &mechanism() const
{
return _mechanism;
}

/**
* String representation for security response
* @return string
*/
const std::string &response() const
{
return _response;
}

/**
* String representation in SASL PLAIN mode
* @return string
Expand All @@ -115,7 +184,7 @@ class Login
// append other elements
return result.append(_user).append("\0",1).append(_password);
}

/**
* Comparison operator
* @param that
Expand All @@ -124,7 +193,10 @@ class Login
bool operator==(const Login &that) const
{
// username and password must match
return _user == that._user && _password == that._password;
return _user == that._user &&
_password == that._password &&
_mechanism == that._mechanism &&
_response == that._response;
}

/**
Expand All @@ -146,10 +218,13 @@ class Login
bool operator<(const Login &that) const
{
// compare users
if (_user != that._user) return _user < that._user;

if (_user != that._user) return _user < that._user;
// compare passwords
return _password < that._password;
if (_password != that._password) return _password < that._password;
// compare mechanisms
if (_mechanism != that._mechanism) return _mechanism < that._mechanism;
// compare responses
return _response < that._response;
}

/**
Expand All @@ -161,7 +236,10 @@ class Login
friend std::ostream &operator<<(std::ostream &stream, const Login &login)
{
// write username and password
return stream << login._user << ":" << login._password;
return stream << login._user << ":"
<< login._password << ":"
<< login._mechanism << ":"
<< login._response;
}

};
Expand Down
2 changes: 1 addition & 1 deletion src/connectionstartframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ class ConnectionStartFrame : public ConnectionFrame
if (!properties.contains("capabilities")) properties["capabilities"] = capabilities;

// send back a connection start ok frame
connection->send(ConnectionStartOKFrame(properties, "PLAIN", connection->login().saslPlain(), "en_US"));
connection->send(ConnectionStartOKFrame(properties, connection->login().mechanism(), connection->login().response(), "en_US"));

// done
return true;
Expand Down