diff --git a/User.cpp b/User.cpp index f37d6037..7436046c 100644 --- a/User.cpp +++ b/User.cpp @@ -827,9 +827,7 @@ bool CUser::CheckPass(const CString& sPass) const { return (sPass == m_sPass); } - CString sSaltedPass = sPass + m_sPassSalt; - - return (m_sPass.Equals(sSaltedPass.MD5())); + return m_sPass.Equals(CUtils::SaltedHash(sPass, m_sPassSalt)); } /*CClient* CUser::GetClient() { diff --git a/Utils.cpp b/Utils.cpp index 2f10f455..2b98a562 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -166,29 +166,16 @@ unsigned long CUtils::GetLongIP(const CString& sIP) { CString CUtils::GetHashPass() { while (true) { - char* pass = CUtils::GetPass("Enter Password"); - char* pass1 = (char*) malloc(strlen(pass) +1); - strcpy(pass1, pass); // Make a copy of this since it is stored in a static buffer and will be overwritten when we fill pass2 below - memset((char*) pass, 0, strlen(pass)); // null out our pass so it doesn't sit in memory - char* pass2 = CUtils::GetPass("Confirm Password"); - int iLen = strlen(pass1); + CString pass1 = CUtils::GetPass("Enter Password"); + CString pass2 = CUtils::GetPass("Confirm Password"); - if (strcmp(pass1, pass2) != 0) { + if (!pass1.Equals(pass2, true)) { CUtils::PrintError("The supplied passwords did not match"); - } else if (!iLen) { + } else if (pass1.empty()) { CUtils::PrintError("You can not use an empty password"); } else { - CString sRet((const char*) CMD5(pass1, iLen)); - memset((char*) pass1, 0, iLen); // null out our pass so it doesn't sit in memory - memset((char*) pass2, 0, strlen(pass2)); // null out our pass so it doesn't sit in memory - free(pass1); - - return sRet; + return pass1.MD5(); } - - memset((char*) pass1, 0, iLen); // null out our pass so it doesn't sit in memory - memset((char*) pass2, 0, strlen(pass2)); // null out our pass so it doesn't sit in memory - free(pass1); } return ""; @@ -196,43 +183,19 @@ CString CUtils::GetHashPass() { CString CUtils::GetSaltedHashPass(CString& sSalt) { sSalt = GetSalt(); - unsigned int uiSaltLength = sSalt.length(); - const char *pSalt = sSalt.c_str(); while (true) { - char* pass = CUtils::GetPass("Enter Password"); - char* pass1 = (char *) malloc(strlen(pass) + 1); - // Make a copy of this since it is stored in a static buffer and will be overwritten when we fill pass2 below - strcpy(pass1, pass); - // null out our pass so it doesn't sit in memory - memset(pass, 0, strlen(pass)); - char* pass2 = CUtils::GetPass("Confirm Password"); - int iLen = strlen(pass1); + CString pass1 = CUtils::GetPass("Enter Password"); + CString pass2 = CUtils::GetPass("Confirm Password"); - if (strcmp(pass1, pass2) != 0) { + if (!pass1.Equals(pass2, true)) { CUtils::PrintError("The supplied passwords did not match"); - } else if (!iLen) { + } else if (pass1.empty()) { CUtils::PrintError("You can not use an empty password"); } else { // Construct the salted pass - char *salted_pass = (char *) malloc(iLen + uiSaltLength + 1); - strcpy(salted_pass, pass1); - strcpy(salted_pass + iLen, pSalt); - - CString sRet((const char*) CMD5(salted_pass, iLen + uiSaltLength)); - // null out our pass so it doesn't sit in memory - memset(salted_pass, 0, iLen + uiSaltLength); - memset(pass1, 0, iLen); - memset(pass2, 0, strlen(pass2)); - free(salted_pass); - free(pass1); - - return sRet; + return SaltedHash(pass1, sSalt); } - - memset((char*) pass1, 0, iLen); // null out our pass so it doesn't sit in memory - memset((char*) pass2, 0, strlen(pass2)); // null out our pass so it doesn't sit in memory - free(pass1); } return ""; @@ -242,6 +205,10 @@ CString CUtils::GetSalt() { return CString::RandomString(20); } +CString CUtils::SaltedHash(const CString& sPass, const CString& sSalt) { + return CString(sPass + sSalt).MD5(); +} + char* CUtils::GetPass(const CString& sPrompt) { PrintPrompt(sPrompt); return getpass(""); diff --git a/Utils.h b/Utils.h index ba5f96e2..58879635 100644 --- a/Utils.h +++ b/Utils.h @@ -55,6 +55,7 @@ public: static CString GetHashPass(); static CString GetSaltedHashPass(CString& sSalt); static CString GetSalt(); + static CString SaltedHash(const CString& sPass, const CString& sSalt); static char* GetPass(const CString& sPrompt); static bool GetInput(const CString& sPrompt, CString& sRet, const CString& sDefault = "", const CString& sHint = ""); static bool GetBoolInput(const CString& sPrompt, bool bDefault); diff --git a/man/znc.1 b/man/znc.1 index 3b2618f9..875a7fb8 100644 --- a/man/znc.1 +++ b/man/znc.1 @@ -57,7 +57,7 @@ Interactively create a new configuration. Hash a password for use in .IR znc.conf . .B znc -uses MD5 for hashing. +uses MD5 for hashing and can use salted hashes. .TP .BR \-p ", " \-\-makepem Generate diff --git a/modules/webadmin.cpp b/modules/webadmin.cpp index 71fcd443..bafdb348 100644 --- a/modules/webadmin.cpp +++ b/modules/webadmin.cpp @@ -999,8 +999,8 @@ CUser* CWebAdminSock::GetNewUser(CString& sPageRet, CUser* pUser) { if (!sArg.empty()) { CString sSalt = CUtils::GetSalt(); - CString sSaltedPass = sArg + sSalt; - pNewUser->SetPass(sSaltedPass.MD5(), true, sSalt); + CString sHash = CUtils::SaltedHash(sArg, sSalt); + pNewUser->SetPass(sHash, true, sSalt); } VCString vsArgs;