mirror of
https://github.com/znc/znc.git
synced 2026-03-28 17:42:41 +01:00
Various SASL changes
This commit is contained in:
@@ -41,6 +41,12 @@ class CAuthBase : private CCoreTranslationMixin {
|
||||
CZNCSock* pSock)
|
||||
: m_sUsername(sUsername), m_sPassword(sPassword), m_pSock(pSock) {}
|
||||
|
||||
// If a module tries to do std::make_shared, the vtable of the mutex inside
|
||||
// shared_ptr will point to the code in the module, and will crash when the
|
||||
// module is unloaded, e.g. shutdown. This function forces the creation of
|
||||
// shared_ptr in the 'znc' binary instead of in the module.
|
||||
static std::shared_ptr<CAuthBase> WrapPointer(CAuthBase*);
|
||||
|
||||
virtual ~CAuthBase() {}
|
||||
|
||||
CAuthBase(const CAuthBase&) = delete;
|
||||
@@ -96,6 +102,17 @@ class CClientAuth : public CAuthBase {
|
||||
CClient* m_pClient;
|
||||
};
|
||||
|
||||
// Workaround SWIG bug, TODO report it
|
||||
#ifndef SWIG
|
||||
/** Username+password auth, which reports success/failure to client via SASL. */
|
||||
class CClientSASLAuth : public CClientAuth {
|
||||
public:
|
||||
using CClientAuth::CClientAuth;
|
||||
void AcceptedLogin(CUser& User) override;
|
||||
void RefusedLogin(const CString& sReason) override;
|
||||
};
|
||||
#endif
|
||||
|
||||
class CClient : public CIRCSocket {
|
||||
public:
|
||||
CClient();
|
||||
@@ -250,6 +267,16 @@ class CClient : public CIRCSocket {
|
||||
CIRCSock* GetIRCSock();
|
||||
CString GetFullName() const;
|
||||
|
||||
/** Sends AUTHENTIATE message to client.
|
||||
* It encodes it to Base64 and splits to multiple IRC messages if necessary.
|
||||
*/
|
||||
void SendSASLChallenge(CString sMessage);
|
||||
void RefuseSASLLogin(const CString& sReason);
|
||||
void AcceptSASLLogin(CUser& User);
|
||||
// Like CZNC::AuthUser() but also stores the pointer, and calls Invalidate()
|
||||
// if the client is destroyed.
|
||||
void StartPasswordCheck(std::shared_ptr<CAuthBase> spAuth);
|
||||
|
||||
private:
|
||||
void HandleCap(const CMessage& Message);
|
||||
void RespondCap(const CString& sResponse);
|
||||
@@ -266,14 +293,14 @@ class CClient : public CIRCSocket {
|
||||
unsigned int DetachChans(const std::set<CChan*>& sChans);
|
||||
|
||||
bool OnActionMessage(CActionMessage& Message);
|
||||
void OnAuthenticateMessage(CAuthenticateMessage& Message);
|
||||
void OnAuthenticateMessage(const CAuthenticateMessage& Message);
|
||||
void AbortSASL(const CString& sFullIRCLine);
|
||||
bool IsDuringSASL() const { return !m_sSASLMechanism.empty(); }
|
||||
|
||||
/**
|
||||
* Fills all available SASL mechanisms in the passed set, and returns a comma-joined string of those mechanisms.
|
||||
* @param ssMechanisms Set of supported mechanisms, filled by this method.
|
||||
* @return A comma-joined string of supported mechanisms.
|
||||
* Returns set of all available SASL mechanisms.
|
||||
*/
|
||||
CString EnumerateSASLMechanisms(SCString& ssMechanisms);
|
||||
SCString EnumerateSASLMechanisms() const;
|
||||
|
||||
bool OnCTCPMessage(CCTCPMessage& Message);
|
||||
bool OnJoinMessage(CJoinMessage& Message);
|
||||
@@ -305,8 +332,7 @@ class CClient : public CIRCSocket {
|
||||
bool m_bBatch;
|
||||
bool m_bEchoMessage;
|
||||
bool m_bSelfMessage;
|
||||
bool m_bSASL;
|
||||
bool m_bSASLAuthenticating;
|
||||
bool m_bSASLCap;
|
||||
bool m_bPlaybackActive;
|
||||
CUser* m_pUser;
|
||||
CIRCNetwork* m_pNetwork;
|
||||
@@ -316,11 +342,15 @@ class CClient : public CIRCSocket {
|
||||
CString m_sNetwork;
|
||||
CString m_sIdentifier;
|
||||
CString m_sSASLBuffer;
|
||||
// Set while the exchange is in progress
|
||||
CString m_sSASLMechanism;
|
||||
// Username who successfully logged in using SASL. This is not a CUser*
|
||||
// because between the 903 and CAP END the user could have been deleted.
|
||||
CString m_sSASLUser;
|
||||
std::shared_ptr<CAuthBase> m_spAuth;
|
||||
SCString m_ssAcceptedCaps;
|
||||
SCString m_ssSupportedTags;
|
||||
SCString m_ssPreviouslyFailedSASLMechanisms;
|
||||
// The capabilities supported by the ZNC core - capability names mapped to
|
||||
// change handler. Note: this lists caps which don't require support on IRC
|
||||
// server.
|
||||
|
||||
@@ -1363,40 +1363,39 @@ class CModule {
|
||||
*/
|
||||
virtual void OnClientCapRequest(CClient* pClient, const CString& sCap,
|
||||
bool bState);
|
||||
|
||||
/** Called when a client requests SASL authentication. Use ssMechanisms.insert("MECHANISM")
|
||||
* for announcing SASL mechanisms which your module supports.
|
||||
* @param ssMechanisms The set of supported SASL mechanisms to append to.
|
||||
*/
|
||||
virtual void OnClientGetSASLMechanisms(SCString& ssMechanisms);
|
||||
/** Called when a client has selected a SASL mechanism for SASL authentication.
|
||||
* If implementing a SASL authentication mechanism, set sResponse to specify an initial challenge
|
||||
* message to send to the client. Otherwise, an empty response will be sent.
|
||||
* If implementing a SASL authentication mechanism, set sResponse to
|
||||
* specify an initial challenge message to send to the client. Otherwise, an
|
||||
* empty response will be sent. To avoid sending any immediate response,
|
||||
* return HALT; in that case the module should schedule calling
|
||||
* GetClient()->SendSASLChallenge() with the initial response: in IRC SASL,
|
||||
* server always responds first.
|
||||
* @param sMechanism The SASL mechanism selected by the client.
|
||||
* @param sResponse The optional value of an initial SASL challenge message to send to the client.
|
||||
* @param sResponse The optional value of an initial SASL challenge message
|
||||
* to send to the client.
|
||||
*/
|
||||
virtual EModRet OnClientSASLServerInitialChallenge(
|
||||
const CString& sMechanism, CString& sResponse);
|
||||
/** Called when a client is sending us a SASL message after the mechanism was selected.
|
||||
* If implementing a SASL authentication mechanism, check the passed
|
||||
* credentials, then either request more data by sending a challenge in
|
||||
* sMechanismResponse, reject authentication by setting
|
||||
* bAuthenticationSuccess to false, or accept authentication by setting
|
||||
* bAuthenticationSuccess to true and setting sUser to the authenticated
|
||||
* user name.
|
||||
* GetClient()->SendSASLChallenge(), or reject authentication by calling
|
||||
* GetClient()->RefuseSASLLogin(), or accept it by calling
|
||||
* GetClient()->AcceptSASLLogin().
|
||||
* @param sMechanism The SASL mechanism selected by the client.
|
||||
* @param sBuffer The SASL opaque value/credentials sent by the client.
|
||||
* @param sUser The optional name of the authenticated user to log in the
|
||||
* user as, if authentication is accepted.
|
||||
* @param sMechanismResponse The optional value of a SASL challenge message
|
||||
* to reply to the client to ask for more data.
|
||||
* @param bAuthenticationSuccess If sMechanismResponse is not set, whether
|
||||
* to accept or reject the authentication request.
|
||||
* @param sMessage The SASL opaque value/credentials sent by the client,
|
||||
* after debase64ing and concatenating if it was split.
|
||||
*/
|
||||
virtual EModRet OnClientSASLAuthenticate(const CString& sMechanism,
|
||||
const CString& sBuffer,
|
||||
CString& sUser,
|
||||
CString& sMechanismResponse,
|
||||
bool& bAuthenticationSuccess);
|
||||
const CString& sMessage);
|
||||
/** Called when a client sent '*' to abort SASL, or aborted it for another reason. */
|
||||
virtual void OnClientSASLAborted();
|
||||
|
||||
/** Called when a module is going to be loaded.
|
||||
* @param sModName name of the module.
|
||||
@@ -1699,13 +1698,13 @@ class CModules : public std::vector<CModule*>, private CCoreTranslationMixin {
|
||||
bool IsClientCapSupported(CClient* pClient, const CString& sCap,
|
||||
bool bState);
|
||||
bool OnClientCapRequest(CClient* pClient, const CString& sCap, bool bState);
|
||||
|
||||
bool OnClientGetSASLMechanisms(SCString& ssMechanisms);
|
||||
bool OnClientSASLAborted();
|
||||
bool OnClientSASLServerInitialChallenge(const CString& sMechanism,
|
||||
CString& sResponse);
|
||||
bool OnClientSASLAuthenticate(const CString& sMechanism,
|
||||
const CString& sBuffer, CString& sUser,
|
||||
CString& sResponse,
|
||||
bool& bAuthenticationSuccess);
|
||||
const CString& sBuffer);
|
||||
|
||||
bool OnModuleLoading(const CString& sModName, const CString& sArgs,
|
||||
CModInfo::EModuleType eType, bool& bSuccess,
|
||||
|
||||
Reference in New Issue
Block a user