Add CUtils::SaltedHash() for doing salted hashes and do some cleanup

The stuff in CUtils::GetHashPass() and CUtils::GetSaltedHashPass() shouldn't
hurt, since we don't do such stuff in other places for passwords either.

This should improve the readability of the code a lot.


git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1324 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
psychon
2009-01-08 15:57:32 +00:00
parent efcbf7884f
commit a3169af5bd
5 changed files with 19 additions and 53 deletions

View File

@@ -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() {

View File

@@ -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("");

View File

@@ -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);

View File

@@ -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

View File

@@ -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;