From cd63bae0068326e004a0f138d58024da7c83950d Mon Sep 17 00:00:00 2001 From: psychon Date: Mon, 7 Sep 2009 18:55:07 +0000 Subject: [PATCH] Add sha256 support This imports the sha256 code from http://www.ouah.org/ogay/sha2/ (The other hashes from sha-2 were removed). sha256 is a much stronger hashing algorithm than md5 is (There were successful birthday attacks against md5). All the code now defaults to creating sha256 salted hashes (The salting used is the same as before). Old znc.conf files can still be read. git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1618 726aef4b-f618-498e-8847-2d620e286838 --- Makefile.in | 2 +- SHA256.cpp | 229 +++++++++++++++++++++++++++++++++++++++++++ SHA256.h | 57 +++++++++++ User.cpp | 30 +++--- User.h | 20 +++- Utils.cpp | 11 ++- Utils.h | 6 +- ZNCString.cpp | 23 ++++- ZNCString.h | 1 + main.cpp | 2 +- modules/admin.cpp | 6 +- modules/webadmin.cpp | 4 +- znc.cpp | 23 +++-- 13 files changed, 380 insertions(+), 34 deletions(-) create mode 100644 SHA256.cpp create mode 100644 SHA256.h 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); } }