From 993dbbbd75063ebddf43d91cd276b900052e8237 Mon Sep 17 00:00:00 2001 From: Vincent Li Date: Fri, 3 Oct 2025 22:09:46 +0000 Subject: [PATCH] chpasswd.cgi: Fixes bug12755 commit a461fd70445aec9dfa34bf9c5a29a85e0ad0e2fe Author: Adolf Belka Date: Sat May 10 12:30:56 2025 +0200 chpasswd.cgi: Fixes bug12755 - v3 with password verification correction - v3 version based on feedback from @Michael to use the status value returned from using the htpasswd command. - Also simplified the whole section to carry out the change if the status is 0, ie all went well, otherwise give an error but without identifying if the error is in the username or the password. This makes it more secure as any attacker only knows it failed and doesn't know if any part of the authentication was correct or not. - Changed the error messages in line with this so the language file changes are in the other part of this patch set submission. - Tested out on my vm test bed and worked fine. If the username was incorrect or the password was incorrect or both were incorrect the same error message is given. If both are correct then the update is carried out. Fixes: bug12755 Tested-by: Adolf Belka Signed-off-by: Adolf Belka Signed-off-by: Michael Tremer commit 9c0dab3d3ca807e836823253aced80a14bc1970a Author: Michael Tremer Date: Wed May 7 09:06:12 2025 +0000 chpasswd.cgi: Add missing $ Signed-off-by: Michael Tremer commit 4c39e38f90fea60ef62e07267fd84f1b89de0297 Author: Adolf Belka Date: Tue May 6 16:10:11 2025 +0200 chpasswd.cgi: Make swroot refs the same as for other cgi files - This uses the swroot definition from general-functions.pl and makes the definition the same as used in the majority of other IPFire cgi files. Tested-by: Adolf Belka Signed-off-by: Adolf Belka Signed-off-by: Michael Tremer commit 6c1549ff7a9c8e3f9f17a29a6b169fce175fea42 Author: Adolf Belka Date: Tue May 6 16:10:09 2025 +0200 chpasswd.cgi: Fixes bug12755 - proxy auth password problem longer than 8 chars - The existing version of the perl module Apache::Htpasswd was using the crypt hash for the password hashing, which is very insecure. The only alternative with this module is the md5 and sha1 hashes which are also considered weak now. - The module was last updated in Nov 2012 and there is no alternative module available. - This patch replaces that perl module with using the apache htpasswd program. This can be set to use the bcrypt hash which is considered secure. This is used for the generation of the root and admin passwords during the IPFire install. - Tested out on my vm testbed system and the password for a specific user name was changed successfully without any restriction to the length of the password. - Existing passwords with the existing md5 or crypt options will still work as htpasswd can manage different encoding hashes in the one file. Fixes: bug12755 Tested-by: Adolf Belka Signed-off-by: Adolf Belka Signed-off-by: Michael Tremer Signed-off-by: Vincent Li --- html/cgi-bin/chpasswd.cgi | 37 ++++++++++++++----------------------- langs/en/cgi-bin/en.pl | 2 +- langs/zh/cgi-bin/zh.pl | 2 +- 3 files changed, 16 insertions(+), 25 deletions(-) diff --git a/html/cgi-bin/chpasswd.cgi b/html/cgi-bin/chpasswd.cgi index 4930c4ca3..0a1a5c9e3 100644 --- a/html/cgi-bin/chpasswd.cgi +++ b/html/cgi-bin/chpasswd.cgi @@ -2,7 +2,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # +# Copyright (C) 2007-2025 IPFire Team # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -20,10 +20,8 @@ ############################################################################### use CGI qw(param); -use Apache::Htpasswd; -use Crypt::PasswdMD5; -$swroot = "/var/ipfire"; +require '/var/ipfire/general-functions.pl'; my %cgiparams; my %mainsettings; @@ -32,8 +30,8 @@ my %proxysettings; $proxysettings{'NCSA_MIN_PASS_LEN'} = 6; ### Initialize environment -&readhash("${swroot}/main/settings", \%mainsettings); -&readhash("${swroot}/proxy/advanced/settings", \%proxysettings); +&readhash("${General::swroot}/main/settings", \%mainsettings); +&readhash("${General::swroot}/proxy/advanced/settings", \%proxysettings); $language = $mainsettings{'LANGUAGE'}; ### Initialize language @@ -42,12 +40,12 @@ if ($language =~ /^(\w+)$/) {$language = $1;} # Uncomment this to force a certain language: # $language='en'; # -require "${swroot}/langs/en.pl"; -require "${swroot}/langs/${language}.pl"; +require "${General::swroot}/langs/en.pl"; +require "${General::swroot}/langs/${language}.pl"; -my $userdb = "$swroot/proxy/advanced/ncsa/passwd"; +my $userdb = "$General::swroot/proxy/advanced/ncsa/passwd"; -&readhash("$swroot/ethernet/settings", \%netsettings); +&readhash("$General::swroot/ethernet/settings", \%netsettings); my $success = 0; @@ -76,20 +74,13 @@ if ($cgiparams{'SUBMIT'} eq $tr{'advproxy chgwebpwd change password'}) goto ERROR; } - my $htpasswd = new Apache::Htpasswd("$userdb"); - - # Check if a user with this name exists - my $old_password = $htpasswd->fetchPass($cgiparams{'USERNAME'}); - if (!$old_password) { - $errormessage = $tr{'advproxy errmsg invalid user'}; - goto ERROR; - } - - # Reset password - if (!$htpasswd->htpasswd($cgiparams{'USERNAME'}, $cgiparams{'NEW_PASSWORD_1'}, - $cgiparams{'OLD_PASSWORD'})) { - $errormessage = $tr{'advproxy errmsg password incorrect'}; + # If the htpasswd verification status is 0 then update the database + # otherwise respond with an error message. + if (&General::system("/usr/bin/htpasswd", "-bv", "$userdb", "$cgiparams{'USERNAME'}", "$cgiparams{'OLD_PASSWORD'}") != 0) { + $errormessage = $tr{'advproxy errmsg invalid user/password'}; goto ERROR; + } else { + &General::system("/usr/bin/htpasswd", "-bB", "-C 10", "$userdb", "$cgiparams{'USERNAME'}", "$cgiparams{'NEW_PASSWORD_1'}"); } $success = 1; diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index 2d2ea9e82..815d63c1d 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -304,7 +304,7 @@ 'advproxy errmsg invalid upstream proxy' => 'Invalid upstream proxy IP/hostname', 'advproxy errmsg invalid upstream proxy username or password setting' => 'Invalid upstream proxy username or password setting', 'advproxy errmsg invalid url' => 'Invalid URL', -'advproxy errmsg invalid user' => 'Username does not exist', +'advproxy errmsg invalid user/password' => 'Error in Username and/or Password', 'advproxy errmsg ldap base dn' => 'LDAP base DN required', 'advproxy errmsg ldap bind dn' => 'LDAP bind DN username and password required', 'advproxy errmsg ldap port' => 'Invalid LDAP port number', diff --git a/langs/zh/cgi-bin/zh.pl b/langs/zh/cgi-bin/zh.pl index 0d86d4638..3e15ea2e9 100644 --- a/langs/zh/cgi-bin/zh.pl +++ b/langs/zh/cgi-bin/zh.pl @@ -299,7 +299,7 @@ 'advproxy errmsg invalid proxy port' => '无效的代理端口', 'advproxy errmsg invalid upstream proxy' => '无效的上游代理IP/主机名', 'advproxy errmsg invalid upstream proxy username or password setting' => '无效的上游代理用户名或密码设置', -'advproxy errmsg invalid user' => '用户名不存在', +'advproxy errmsg invalid user/password' => '无效用户名或密码', 'advproxy errmsg ldap base dn' => '需要LDAP基本DN', 'advproxy errmsg ldap bind dn' => '需要LDAP绑定DN用户名和密码', 'advproxy errmsg ldap port' => '无效的LDAP端口号',