diff --git a/Client.cpp b/Client.cpp index 25012dcc..3423f170 100644 --- a/Client.cpp +++ b/Client.cpp @@ -126,10 +126,16 @@ void CClient::ReadLine(const CString& sData) { return; // Don't forward this msg. ZNC has already registered us. } + } else if (sCommand.Equals("CAP")) { + HandleCap(sLine); + + // Don't let the client talk to the server directly about CAP, + // we don't want anything enabled that znc does not support. + return; } if (!m_pUser) { - // Only NICK, USER and PASS are allowed before login + // Only CAP, NICK, USER and PASS are allowed before login return; } @@ -588,7 +594,7 @@ bool CClient::SendMotd() { } void CClient::AuthUser() { - if (!m_bGotNick || !m_bGotUser) + if (!m_bGotNick || !m_bGotUser || m_bInCap || IsAttached()) return; m_spAuth = new CClientAuth(this, m_sUser, m_sPass); @@ -771,3 +777,26 @@ CString CClient::GetNickMask() const { return GetNick() + "!" + m_pUser->GetIdent() + "@" + sHost; } + +void CClient::RespondCap(const CString& sResponse) +{ + PutClient(":irc.znc.in CAP " + GetNick() + " " + sResponse); +} + +void CClient::HandleCap(const CString& sLine) +{ + CString sSubCmd = sLine.Token(1); + + if (sSubCmd.Equals("LS")) { + RespondCap("LS :"); + m_bInCap = true; + } else if (sSubCmd.Equals("END")) { + m_bInCap = false; + AuthUser(); + } else if (sSubCmd.Equals("REQ")) { + // No capabilities supported for now + RespondCap("NAK :" + sLine.Token(2, true).TrimPrefix_n(":")); + } else if (sSubCmd.Equals("LIST")) { + RespondCap("LIST :"); + } +} diff --git a/Client.h b/Client.h index d00a84d5..aafe6ce4 100644 --- a/Client.h +++ b/Client.h @@ -78,6 +78,7 @@ public: m_bGotPass = false; m_bGotNick = false; m_bGotUser = false; + m_bInCap = false; m_bNamesx = false; m_bUHNames = false; EnableReadLine(); @@ -127,11 +128,14 @@ public: const CIRCSock* GetIRCSock() const; CIRCSock* GetIRCSock(); private: + void HandleCap(const CString& sLine); + void RespondCap(const CString& sResponse); protected: bool m_bGotPass; bool m_bGotNick; bool m_bGotUser; + bool m_bInCap; bool m_bNamesx; bool m_bUHNames; CUser* m_pUser; diff --git a/IRCSock.cpp b/IRCSock.cpp index e9fd034f..9ae123ba 100644 --- a/IRCSock.cpp +++ b/IRCSock.cpp @@ -671,6 +671,9 @@ void CIRCSock::ReadLine(const CString& sData) { } } } + + // Don't forward any CAP stuff to the client + return; } }