Beispiel #1
0
    EModRet OnLoginAttempt(std::shared_ptr<CAuthBase> Auth) override {
        const CString sUser = Auth->GetUsername();
        Csock* pSock = Auth->GetSocket();
        CUser* pUser = CZNC::Get().FindUser(sUser);

        if (pSock == nullptr || pUser == nullptr) return CONTINUE;

        const CString sPubKey = GetKey(pSock);
        DEBUG("User: "******" Key: " << sPubKey);

        if (sPubKey.empty()) {
            DEBUG("Peer got no public key, ignoring");
            return CONTINUE;
        }

        MSCString::const_iterator it = m_PubKeys.find(sUser);
        if (it == m_PubKeys.end()) {
            DEBUG("No saved pubkeys for this client");
            return CONTINUE;
        }

        SCString::const_iterator it2 = it->second.find(sPubKey);
        if (it2 == it->second.end()) {
            DEBUG("Invalid pubkey");
            return CONTINUE;
        }

        // This client uses a valid pubkey for this user, let them in
        DEBUG("Accepted pubkey auth");
        Auth->AcceptLogin(*pUser);

        return HALT;
    }
Beispiel #2
0
void CIMAPSock::ReadLine(const CString& sLine) {
	if (!m_bSentLogin) {
		CString sUsername = m_spAuth->GetUsername();
		m_bSentLogin = true;

		const CString& sFormat = m_pIMAPMod->GetUserFormat();

		if (!sFormat.empty()) {
			if (sFormat.find('%') != CString::npos) {
				sUsername = sFormat.Replace_n("%", sUsername);
			} else {
				sUsername += sFormat;
			}
		}

		Write("AUTH LOGIN " + sUsername + " " + m_spAuth->GetPassword() + "\r\n");
	} else if (sLine.Left(5) == "AUTH ") {
		CUser* pUser = CZNC::Get().FindUser(m_spAuth->GetUsername());

		if (pUser && sLine.StartsWith("AUTH OK")) {
			m_spAuth->AcceptLogin(*pUser);
			m_pIMAPMod->CacheLogin(CString(m_spAuth->GetUsername() + ":" + m_spAuth->GetPassword()).MD5()); // Use MD5 so passes don't sit in memory in plain text
			DEBUG("+++ Successful IMAP lookup");
		} else {
			m_spAuth->RefuseLogin("Invalid Password");
			DEBUG("--- FAILED IMAP lookup");
		}

		m_bSentReply = true;
		Close();
	}
}
Beispiel #3
0
	EModRet OnLoginAttempt(std::shared_ptr<CAuthBase> Auth) override {
		CUser* pUser = CZNC::Get().FindUser(Auth->GetUsername());

		if (!pUser) { // @todo Will want to do some sort of && !m_bAllowCreate in the future
			Auth->RefuseLogin("Invalid User - Halting IMAP Lookup");
			return HALT;
		}

		if (pUser && m_Cache.HasItem(CString(Auth->GetUsername() + ":" + Auth->GetPassword()).MD5())) {
			DEBUG("+++ Found in cache");
			Auth->AcceptLogin(*pUser);
			return HALT;
		}

		CIMAPSock* pSock = new CIMAPSock(this, Auth);
		pSock->Connect(m_sServer, m_uPort, m_bSSL, 20);

		return HALT;
	}
Beispiel #4
0
	EModRet OnLoginAttempt(std::shared_ptr<CAuthBase> Auth) override {
		const CString& sUsername = Auth->GetUsername();
		const CString& sPassword = Auth->GetPassword();
		CUser *pUser(CZNC::Get().FindUser(sUsername));
		sasl_conn_t *sasl_conn(nullptr);
		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", nullptr, nullptr, nullptr, nullptr, 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 = nullptr;
					}

					if (pUser && !pUser->Clone(*pBaseUser, sErr)) {
						DEBUG("saslauth: Clone User [" << CloneUser() << "] failed: " << sErr);
						delete pUser;
						pUser = nullptr;
					}
				}

				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 = nullptr;
				}
			}

			if (pUser) {
				Auth->AcceptLogin(*pUser);
				return HALT;
			}
		}

		return CONTINUE;
	}