diff --git a/Makefile.in b/Makefile.in index cbe97b59..19363acd 100644 --- a/Makefile.in +++ b/Makefile.in @@ -22,7 +22,7 @@ PKGCONFIGDIR := $(libdir)/pkgconfig LIB_SRCS := ZNCString.cpp Csocket.cpp znc.cpp User.cpp IRCSock.cpp Client.cpp DCCBounce.cpp \ DCCSock.cpp Chan.cpp Nick.cpp Server.cpp Modules.cpp MD5.cpp Buffer.cpp Utils.cpp \ - FileUtils.cpp HTTPSock.cpp Template.cpp ClientCommand.cpp Socket.cpp + FileUtils.cpp HTTPSock.cpp Template.cpp ClientCommand.cpp Socket.cpp SHA256.cpp BIN_SRCS := main.cpp LIB_OBJS := $(patsubst %cpp,%o,$(LIB_SRCS)) BIN_OBJS := $(patsubst %cpp,%o,$(BIN_SRCS)) diff --git a/SHA256.cpp b/SHA256.cpp new file mode 100644 index 00000000..3ae4c8ce --- /dev/null +++ b/SHA256.cpp @@ -0,0 +1,229 @@ +/* + * FIPS 180-2 SHA-224/256/384/512 implementation + * Last update: 02/02/2007 + * Issue date: 04/30/2005 + * + * Copyright (C) 2005, 2007 Olivier Gay + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "SHA256.h" + +#define SHFR(x, n) (x >> n) +#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n))) +#define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n))) +#define CH(x, y, z) ((x & y) ^ (~x & z)) +#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) + +#define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3)) +#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10)) + +#define UNPACK32(x, str) \ +{ \ + *((str) + 3) = (uint8_t) ((x) ); \ + *((str) + 2) = (uint8_t) ((x) >> 8); \ + *((str) + 1) = (uint8_t) ((x) >> 16); \ + *((str) + 0) = (uint8_t) ((x) >> 24); \ +} + +#define PACK32(str, x) \ +{ \ + *(x) = ((uint32_t) *((str) + 3) ) \ + | ((uint32_t) *((str) + 2) << 8) \ + | ((uint32_t) *((str) + 1) << 16) \ + | ((uint32_t) *((str) + 0) << 24); \ +} + +/* Macros used for loops unrolling */ + +#define SHA256_SCR(i) \ +{ \ + w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \ + + SHA256_F3(w[i - 15]) + w[i - 16]; \ +} + +#define SHA256_EXP(a, b, c, d, e, f, g, h, j) \ +{ \ + t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \ + + sha256_k[j] + w[j]; \ + t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \ + wv[d] += t1; \ + wv[h] = t1 + t2; \ +} + +uint32_t sha256_h0[8] = + {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + +uint32_t sha256_k[64] = + {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}; + +/* SHA-256 functions */ + +static void sha256_transf(sha256_ctx *ctx, const unsigned char *message, + unsigned int block_nb) +{ + uint32_t w[64]; + uint32_t wv[8]; + uint32_t t1, t2; + const unsigned char *sub_block; + int i; + + int j; + + for (i = 0; i < (int) block_nb; i++) { + sub_block = message + (i << 6); + + for (j = 0; j < 16; j++) { + PACK32(&sub_block[j << 2], &w[j]); + } + + for (j = 16; j < 64; j++) { + SHA256_SCR(j); + } + + for (j = 0; j < 8; j++) { + wv[j] = ctx->h[j]; + } + + for (j = 0; j < 64; j++) { + t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) + + sha256_k[j] + w[j]; + t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]); + wv[7] = wv[6]; + wv[6] = wv[5]; + wv[5] = wv[4]; + wv[4] = wv[3] + t1; + wv[3] = wv[2]; + wv[2] = wv[1]; + wv[1] = wv[0]; + wv[0] = t1 + t2; + } + + for (j = 0; j < 8; j++) { + ctx->h[j] += wv[j]; + } + } +} + +void sha256(const unsigned char *message, unsigned int len, unsigned char *digest) +{ + sha256_ctx ctx; + + sha256_init(&ctx); + sha256_update(&ctx, message, len); + sha256_final(&ctx, digest); +} + +void sha256_init(sha256_ctx *ctx) +{ + int i; + for (i = 0; i < 8; i++) { + ctx->h[i] = sha256_h0[i]; + } + + ctx->len = 0; + ctx->tot_len = 0; +} + +void sha256_update(sha256_ctx *ctx, const unsigned char *message, + unsigned int len) +{ + unsigned int block_nb; + unsigned int new_len, rem_len, tmp_len; + const unsigned char *shifted_message; + + tmp_len = SHA256_BLOCK_SIZE - ctx->len; + rem_len = len < tmp_len ? len : tmp_len; + + memcpy(&ctx->block[ctx->len], message, rem_len); + + if (ctx->len + len < SHA256_BLOCK_SIZE) { + ctx->len += len; + return; + } + + new_len = len - rem_len; + block_nb = new_len / SHA256_BLOCK_SIZE; + + shifted_message = message + rem_len; + + sha256_transf(ctx, ctx->block, 1); + sha256_transf(ctx, shifted_message, block_nb); + + rem_len = new_len % SHA256_BLOCK_SIZE; + + memcpy(ctx->block, &shifted_message[block_nb << 6], + rem_len); + + ctx->len = rem_len; + ctx->tot_len += (block_nb + 1) << 6; +} + +void sha256_final(sha256_ctx *ctx, unsigned char *digest) +{ + unsigned int block_nb; + unsigned int pm_len; + unsigned int len_b; + + int i; + + block_nb = (1 + ((SHA256_BLOCK_SIZE - 9) + < (ctx->len % SHA256_BLOCK_SIZE))); + + len_b = (ctx->tot_len + ctx->len) << 3; + pm_len = block_nb << 6; + + memset(ctx->block + ctx->len, 0, pm_len - ctx->len); + ctx->block[ctx->len] = 0x80; + UNPACK32(len_b, ctx->block + pm_len - 4); + + sha256_transf(ctx, ctx->block, block_nb); + + for (i = 0 ; i < 8; i++) { + UNPACK32(ctx->h[i], &digest[i << 2]); + } +} diff --git a/SHA256.h b/SHA256.h new file mode 100644 index 00000000..a130a7f5 --- /dev/null +++ b/SHA256.h @@ -0,0 +1,57 @@ +/* + * FIPS 180-2 SHA-224/256/384/512 implementation + * Last update: 02/02/2007 + * Issue date: 04/30/2005 + * + * Copyright (C) 2005, 2007 Olivier Gay + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef SHA2_H +#define SHA2_H + +#define SHA256_DIGEST_SIZE ( 256 / 8) +#define SHA256_BLOCK_SIZE ( 512 / 8) + +#include + +typedef struct { + unsigned int tot_len; + unsigned int len; + unsigned char block[2 * SHA256_BLOCK_SIZE]; + uint32_t h[8]; +} sha256_ctx; + +void sha256_init(sha256_ctx * ctx); +void sha256_update(sha256_ctx *ctx, const unsigned char *message, + unsigned int len); +void sha256_final(sha256_ctx *ctx, unsigned char *digest); +void sha256(const unsigned char *message, unsigned int len, + unsigned char *digest); + +#endif /* !SHA2_H */ + diff --git a/User.cpp b/User.cpp index 17006d78..188dfd25 100644 --- a/User.cpp +++ b/User.cpp @@ -32,7 +32,7 @@ CUser::CUser(const CString& sUserName) { m_MotdBuffer.SetLineCount(200); // This should be more than enough motd lines m_bMultiClients = true; m_bBounceDCCs = true; - m_bPassHashed = false; + m_eHashType = HASH_NONE; m_bUseClientIP = false; m_bDenyLoadMod = false; m_bAdmin= false; @@ -324,7 +324,7 @@ bool CUser::Clone(const CUser& User, CString& sErrorRet, bool bCloneChans) { } if (!User.GetPass().empty()) { - SetPass(User.GetPass(), User.IsPassHashed(), User.GetPassSalt()); + SetPass(User.GetPass(), User.GetPassHashType(), User.GetPassSalt()); } SetNick(User.GetNick(false)); @@ -600,11 +600,14 @@ bool CUser::PrintLine(CFile& File, const CString& sName, const CString& sValue) bool CUser::WriteConfig(CFile& File) { File.Write("\n"); - if (IsPassHashed()) { + if (m_eHashType != HASH_NONE) { + CString sHash = "md5"; + if (m_eHashType == HASH_SHA256) + sHash = "sha256"; if (m_sPassSalt.empty()) { - PrintLine(File, "Pass", "md5#" + GetPass()); + PrintLine(File, "Pass", sHash + "#" + GetPass()); } else { - PrintLine(File, "Pass", "md5#" + GetPass() + "#" + m_sPassSalt + "#"); + PrintLine(File, "Pass", sHash + "#" + GetPass() + "#" + m_sPassSalt + "#"); } } else { PrintLine(File, "Pass", "plain#" + GetPass()); @@ -883,11 +886,16 @@ CServer* CUser::GetCurrentServer() const { } bool CUser::CheckPass(const CString& sPass) const { - if (!m_bPassHashed) { + switch (m_eHashType) + { + case HASH_MD5: + return m_sPass.Equals(CUtils::SaltedMD5Hash(sPass, m_sPassSalt)); + case HASH_SHA256: + return m_sPass.Equals(CUtils::SaltedSHA256Hash(sPass, m_sPassSalt)); + case HASH_NONE: + default: return (sPass == m_sPass); } - - return m_sPass.Equals(CUtils::SaltedHash(sPass, m_sPassSalt)); } /*CClient* CUser::GetClient() { @@ -1094,9 +1102,9 @@ void CUser::SetAltNick(const CString& s) { m_sAltNick = s; } void CUser::SetIdent(const CString& s) { m_sIdent = s; } void CUser::SetRealName(const CString& s) { m_sRealName = s; } void CUser::SetVHost(const CString& s) { m_sVHost = s; } -void CUser::SetPass(const CString& s, bool bHashed, const CString& sSalt) { +void CUser::SetPass(const CString& s, eHashType eHash, const CString& sSalt) { m_sPass = s; - m_bPassHashed = bHashed; + m_eHashType = eHash; m_sPassSalt = sSalt; } void CUser::SetMultiClients(bool b) { m_bMultiClients = b; } @@ -1154,7 +1162,7 @@ const CString& CUser::GetIdent(bool bAllowDefault) const { return (bAllowDefault const CString& CUser::GetRealName() const { return m_sRealName.empty() ? m_sUserName : m_sRealName; } const CString& CUser::GetVHost() const { return m_sVHost; } const CString& CUser::GetPass() const { return m_sPass; } -bool CUser::IsPassHashed() const { return m_bPassHashed; } +CUser::eHashType CUser::GetPassHashType() const { return m_eHashType; } const CString& CUser::GetPassSalt() const { return m_sPassSalt; } bool CUser::ConnectPaused() { diff --git a/User.h b/User.h index 862021a1..3063de1e 100644 --- a/User.h +++ b/User.h @@ -35,6 +35,20 @@ public: CUser(const CString& sUserName); ~CUser(); + enum eHashType { + HASH_NONE, + HASH_MD5, + HASH_SHA256, + + HASH_DEFAULT = HASH_SHA256 + }; + + // If you change the default hash here and in HASH_DEFAULT, + // don't forget CUtils::sDefaultHash! + static CString SaltedHash(const CString& sPass, const CString& sSalt) { + return CUtils::SaltedSHA256Hash(sPass, sSalt); + } + bool PrintLine(CFile& File, const CString& sName, const CString& sValue); bool WriteConfig(CFile& File); CChan* FindChan(const CString& sName) const; @@ -131,7 +145,7 @@ public: void SetIdent(const CString& s); void SetRealName(const CString& s); void SetVHost(const CString& s); - void SetPass(const CString& s, bool bHashed, const CString& sSalt = ""); + void SetPass(const CString& s, eHashType eHash, const CString& sSalt = ""); void SetBounceDCCs(bool b); void SetMultiClients(bool b); void SetUseClientIP(bool b); @@ -169,7 +183,7 @@ public: const CString& GetRealName() const; const CString& GetVHost() const; const CString& GetPass() const; - bool IsPassHashed() const; + eHashType GetPassHashType() const; const CString& GetPassSalt() const; const set& GetAllowedHosts() const; const CString& GetTimestampFormat() const; @@ -228,6 +242,7 @@ protected: MCString m_mssCTCPReplies; CString m_sTimestampFormat; float m_fTimezoneOffset; + eHashType m_eHashType; // Paths CString m_sUserPath; @@ -239,7 +254,6 @@ protected: CBuffer m_QueryBuffer; bool m_bMultiClients; bool m_bBounceDCCs; - bool m_bPassHashed; bool m_bUseClientIP; bool m_bDenyLoadMod; bool m_bAdmin; diff --git a/Utils.cpp b/Utils.cpp index 7204c70f..6efe5c9c 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -163,6 +163,9 @@ CString CUtils::GetHashPass() { } } +// If you change this here and in GetSaltedHashPass(), +// don't forget CUser::HASH_DEFAULT! +const CString CUtils::sDefaultHash = "sha256"; CString CUtils::GetSaltedHashPass(CString& sSalt) { sSalt = GetSalt(); @@ -176,7 +179,7 @@ CString CUtils::GetSaltedHashPass(CString& sSalt) { CUtils::PrintError("You can not use an empty password"); } else { // Construct the salted pass - return SaltedHash(pass1, sSalt); + return SaltedSHA256Hash(pass1, sSalt); } } } @@ -185,10 +188,14 @@ CString CUtils::GetSalt() { return CString::RandomString(20); } -CString CUtils::SaltedHash(const CString& sPass, const CString& sSalt) { +CString CUtils::SaltedMD5Hash(const CString& sPass, const CString& sSalt) { return CString(sPass + sSalt).MD5(); } +CString CUtils::SaltedSHA256Hash(const CString& sPass, const CString& sSalt) { + return CString(sPass + sSalt).SHA256(); +} + CString CUtils::GetPass(const CString& sPrompt) { PrintPrompt(sPrompt); return getpass(""); diff --git a/Utils.h b/Utils.h index e007cbb3..337f7ec6 100644 --- a/Utils.h +++ b/Utils.h @@ -60,10 +60,14 @@ public: static void PrintPrompt(const CString& sMessage); static void PrintAction(const CString& sMessage); static void PrintStatus(bool bSuccess, const CString& sMessage = ""); + + static const CString sDefaultHash; + static CString GetHashPass(); static CString GetSaltedHashPass(CString& sSalt); static CString GetSalt(); - static CString SaltedHash(const CString& sPass, const CString& sSalt); + static CString SaltedMD5Hash(const CString& sPass, const CString& sSalt); + static CString SaltedSHA256Hash(const CString& sPass, const CString& sSalt); static CString 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/ZNCString.cpp b/ZNCString.cpp index e0a84be1..2c53ba8b 100644 --- a/ZNCString.cpp +++ b/ZNCString.cpp @@ -8,8 +8,9 @@ #include "ZNCString.h" #include "FileUtils.h" -#include "MD5.h" #include "Utils.h" +#include "MD5.h" +#include "SHA256.h" #include using std::stringstream; @@ -867,6 +868,26 @@ CString CString::MD5() const { return (const char*) CMD5(*this); } +CString CString::SHA256() const { + unsigned char digest[SHA256_DIGEST_SIZE]; + char digest_hex[SHA256_DIGEST_SIZE * 2 + 1]; + const unsigned char *message = (const unsigned char *) c_str(); + + sha256(message, length(), digest); + + sprintf(digest_hex, + "%02x%02x%02x%02x%02x%02x%02x%02x" + "%02x%02x%02x%02x%02x%02x%02x%02x" + "%02x%02x%02x%02x%02x%02x%02x%02x" + "%02x%02x%02x%02x%02x%02x%02x%02x", + digest[ 0], digest[ 1], digest[ 2], digest[ 3], digest[ 4], digest[ 5], digest[ 6], digest[ 7], + digest[ 8], digest[ 9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15], + digest[16], digest[17], digest[18], digest[19], digest[20], digest[21], digest[22], digest[23], + digest[24], digest[25], digest[26], digest[27], digest[28], digest[29], digest[30], digest[31]); + + return digest_hex; +} + #ifdef HAVE_LIBSSL CString CString::Encrypt_n(const CString& sPass, const CString& sIvec) { CString sRet; diff --git a/ZNCString.h b/ZNCString.h index 376eeb6d..cedf289b 100644 --- a/ZNCString.h +++ b/ZNCString.h @@ -125,6 +125,7 @@ public: static CString RandomString(unsigned int uLength); CString MD5() const; + CString SHA256() const; unsigned long Base64Decode(CString& sRet) const; unsigned long Base64Decode(); CString Base64Decode_n() const; diff --git a/main.cpp b/main.cpp index 81c86bda..3d8c60ba 100644 --- a/main.cpp +++ b/main.cpp @@ -153,7 +153,7 @@ int main(int argc, char** argv) { CString sSalt; CString sHash = CUtils::GetSaltedHashPass(sSalt); CUtils::PrintMessage("Use this in the section of your config:"); - CUtils::PrintMessage("Pass = md5#" + sHash + "#" + sSalt + "#"); + CUtils::PrintMessage("Pass = " + CUtils::sDefaultHash + "#" + sHash + "#" + sSalt + "#"); delete pZNC; return 0; diff --git a/modules/admin.cpp b/modules/admin.cpp index abe3b929..e7f16dbd 100644 --- a/modules/admin.cpp +++ b/modules/admin.cpp @@ -240,8 +240,8 @@ class CAdminMod : public CModule { } else if (var == "password") { const CString sSalt = CUtils::GetSalt(); - const CString sHash = CUtils::SaltedHash(value, sSalt); - user->SetPass(sHash, true, sSalt); + const CString sHash = CUser::SaltedHash(value, sSalt); + user->SetPass(sHash, CUser::HASH_DEFAULT, sSalt); PutModule("Password has been changed!!"); } else @@ -391,7 +391,7 @@ class CAdminMod : public CModule { CUser* pNewUser = new CUser(sUsername); CString sSalt = CUtils::GetSalt(); - pNewUser->SetPass(CUtils::SaltedHash(sPassword, sSalt), true, sSalt); + pNewUser->SetPass(CUser::SaltedHash(sPassword, sSalt), CUser::HASH_DEFAULT, sSalt); if (sIRCServer.size()) pNewUser->AddServer(sIRCServer); diff --git a/modules/webadmin.cpp b/modules/webadmin.cpp index 3b0a3462..9eada04d 100644 --- a/modules/webadmin.cpp +++ b/modules/webadmin.cpp @@ -1039,8 +1039,8 @@ CUser* CWebAdminSock::GetNewUser(CString& sPageRet, CUser* pUser) { if (!sArg.empty()) { CString sSalt = CUtils::GetSalt(); - CString sHash = CUtils::SaltedHash(sArg, sSalt); - pNewUser->SetPass(sHash, true, sSalt); + CString sHash = CUser::SaltedHash(sArg, sSalt); + pNewUser->SetPass(sHash, CUser::HASH_DEFAULT, sSalt); } VCString vsArgs; diff --git a/znc.cpp b/znc.cpp index bab69c2a..d225dc31 100644 --- a/znc.cpp +++ b/znc.cpp @@ -706,7 +706,7 @@ bool CZNC::WriteNewConfig(const CString& sConfigFile) { vsLines.push_back(""); CString sSalt; sAnswer = CUtils::GetSaltedHashPass(sSalt); - vsLines.push_back("\tPass = md5#" + sAnswer + "#" + sSalt + "#"); + vsLines.push_back("\tPass = " + CUtils::sDefaultHash + "#" + sAnswer + "#" + sSalt + "#"); if (CUtils::GetBoolInput("Would you like this user to be an admin?", bFirstUser)) { vsLines.push_back("\tAdmin = true"); @@ -1236,24 +1236,29 @@ bool CZNC::DoRehash(CString& sError) // Pass = // Pass = - // Pass = plain# - // Pass = md5# - // Pass = md5### - // The last one is the md5 hash of 'password' + 'salt' + // Pass = # + // Pass = ### + // 'Salted hash' means hash of 'password' + 'salt' + // Possible hashes are md5 and sha256 if (sValue.Right(1) == "-") { sValue.RightChomp(); sValue.Trim(); - pUser->SetPass(sValue, true); + pUser->SetPass(sValue, CUser::HASH_MD5); } else { CString sMethod = sValue.Token(0, false, "#"); CString sPass = sValue.Token(1, true, "#"); - if (sMethod == "md5") { + if (sMethod == "md5" || sMethod == "sha256") { + CUser::eHashType type = CUser::HASH_MD5; + if (sMethod == "sha256") + type = CUser::HASH_SHA256; + CString sSalt = sPass.Token(1, false, "#"); sPass = sPass.Token(0, false, "#"); - pUser->SetPass(sPass, true, sSalt); + pUser->SetPass(sPass, type, sSalt); } else if (sMethod == "plain") { - pUser->SetPass(sPass, false); + pUser->SetPass(sPass, CUser::HASH_NONE); } else { - pUser->SetPass(sValue, false); + pUser->SetPass(sValue, CUser::HASH_NONE); } }