virtual EModRet OnLoginAttempt(CSmartPtr<CAuthBase> Auth) { CString const user(Auth->GetUsername()); CString const pass(Auth->GetPassword()); CUser* pUser(CZNC::Get().FindUser(user)); sasl_conn_t *sasl_conn(0); if (!pUser) { // @todo Will want to do some sort of && !m_bAllowCreate in the future Auth->RefuseLogin("Invalid User - Halting SASL Authentication"); return HALT; } CString const key(CString(user + ":" + pass).MD5()); if (m_Cache.HasItem(key)) { Auth->AcceptLogin(*pUser); DEBUG("+++ Found in cache"); } else if (sasl_server_new("znc", NULL, NULL, NULL, NULL, cbs, 0, &sasl_conn) == SASL_OK && sasl_checkpass(sasl_conn, user.c_str(), user.size(), pass.c_str(), pass.size()) == SASL_OK) { Auth->AcceptLogin(*pUser); m_Cache.AddItem(key); DEBUG("+++ Successful SASL password check"); } else { Auth->RefuseLogin("SASL Authentication failed"); DEBUG("--- FAILED SASL password check"); } sasl_dispose(&sasl_conn); return HALT; }
virtual EModRet OnLoginAttempt(CSmartPtr<CAuthBase> Auth) { const CString& sUsername = Auth->GetUsername(); const CString& sPassword = Auth->GetPassword(); CUser *pUser(CZNC::Get().FindUser(sUsername)); sasl_conn_t *sasl_conn(NULL); bool bSuccess = false; if (!pUser && !CreateUser()) { return CONTINUE; } const CString sCacheKey(CString(sUsername + ":" + sPassword).MD5()); if (m_Cache.HasItem(sCacheKey)) { bSuccess = true; DEBUG("saslauth: Found [" + sUsername + "] in cache"); } else if (sasl_server_new("znc", NULL, NULL, NULL, NULL, m_cbs, 0, &sasl_conn) == SASL_OK && sasl_checkpass(sasl_conn, sUsername.c_str(), sUsername.size(), sPassword.c_str(), sPassword.size()) == SASL_OK) { m_Cache.AddItem(sCacheKey); DEBUG("saslauth: Successful SASL authentication [" + sUsername + "]"); bSuccess = true; } sasl_dispose(&sasl_conn); if (bSuccess) { if (!pUser) { CString sErr; pUser = new CUser(sUsername); if (ShouldCloneUser()) { CUser *pBaseUser = CZNC::Get().FindUser(CloneUser()); if (!pBaseUser) { DEBUG("saslauth: Clone User [" << CloneUser() << "] User not found"); delete pUser; pUser = NULL; } if (pUser && !pUser->Clone(*pBaseUser, sErr)) { DEBUG("saslauth: Clone User [" << CloneUser() << "] failed: " << sErr); delete pUser; pUser = NULL; } } if (pUser) { // "::" is an invalid MD5 hash, so user won't be able to login by usual method pUser->SetPass("::", CUser::HASH_MD5, "::"); } if (pUser && !CZNC::Get().AddUser(pUser, sErr)) { DEBUG("saslauth: Add user [" << sUsername << "] failed: " << sErr); delete pUser; pUser = NULL; } } if (pUser) { Auth->AcceptLogin(*pUser); return HALT; } } return CONTINUE; }