mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-09 18:45:54 +02:00
commit a461fd70445aec9dfa34bf9c5a29a85e0ad0e2fe Author: Adolf Belka <adolf.belka@ipfire.org> 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 <adolf.belka@ipfire.org> Signed-off-by: Adolf Belka <adolf.belka@ipfire.org> Signed-off-by: Michael Tremer <michael.tremer@ipfire.org> commit 9c0dab3d3ca807e836823253aced80a14bc1970a Author: Michael Tremer <michael.tremer@ipfire.org> Date: Wed May 7 09:06:12 2025 +0000 chpasswd.cgi: Add missing $ Signed-off-by: Michael Tremer <michael.tremer@ipfire.org> commit 4c39e38f90fea60ef62e07267fd84f1b89de0297 Author: Adolf Belka <adolf.belka@ipfire.org> 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 <adolf.belka@ipfire.org> Signed-off-by: Adolf Belka <adolf.belka@ipfire.org> Signed-off-by: Michael Tremer <michael.tremer@ipfire.org> commit 6c1549ff7a9c8e3f9f17a29a6b169fce175fea42 Author: Adolf Belka <adolf.belka@ipfire.org> 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 <adolf.belka@ipfire.org> Signed-off-by: Adolf Belka <adolf.belka@ipfire.org> Signed-off-by: Michael Tremer <michael.tremer@ipfire.org> Signed-off-by: Vincent Li <vincent.mc.li@gmail.com>
281 lines
7.9 KiB
Perl
281 lines
7.9 KiB
Perl
#!/usr/bin/perl
|
|
###############################################################################
|
|
# #
|
|
# IPFire.org - A linux based firewall #
|
|
# Copyright (C) 2007-2025 IPFire Team <info@ipfire.org> #
|
|
# #
|
|
# 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 #
|
|
# the Free Software Foundation, either version 3 of the License, or #
|
|
# (at your option) any later version. #
|
|
# #
|
|
# This program is distributed in the hope that it will be useful, #
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
# GNU General Public License for more details. #
|
|
# #
|
|
# You should have received a copy of the GNU General Public License #
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
|
# #
|
|
###############################################################################
|
|
|
|
use CGI qw(param);
|
|
|
|
require '/var/ipfire/general-functions.pl';
|
|
|
|
my %cgiparams;
|
|
my %mainsettings;
|
|
my %proxysettings;
|
|
|
|
$proxysettings{'NCSA_MIN_PASS_LEN'} = 6;
|
|
|
|
### Initialize environment
|
|
&readhash("${General::swroot}/main/settings", \%mainsettings);
|
|
&readhash("${General::swroot}/proxy/advanced/settings", \%proxysettings);
|
|
$language = $mainsettings{'LANGUAGE'};
|
|
|
|
### Initialize language
|
|
if ($language =~ /^(\w+)$/) {$language = $1;}
|
|
#
|
|
# Uncomment this to force a certain language:
|
|
# $language='en';
|
|
#
|
|
require "${General::swroot}/langs/en.pl";
|
|
require "${General::swroot}/langs/${language}.pl";
|
|
|
|
my $userdb = "$General::swroot/proxy/advanced/ncsa/passwd";
|
|
|
|
&readhash("$General::swroot/ethernet/settings", \%netsettings);
|
|
|
|
my $success = 0;
|
|
|
|
&getcgihash(\%cgiparams);
|
|
|
|
if ($cgiparams{'SUBMIT'} eq $tr{'advproxy chgwebpwd change password'})
|
|
{
|
|
if ($cgiparams{'USERNAME'} eq '')
|
|
{
|
|
$errormessage = $tr{'advproxy errmsg no username'};
|
|
goto ERROR;
|
|
}
|
|
if (($cgiparams{'OLD_PASSWORD'} eq '') || ($cgiparams{'NEW_PASSWORD_1'} eq '') || ($cgiparams{'NEW_PASSWORD_2'} eq ''))
|
|
{
|
|
$errormessage = $tr{'advproxy errmsg no password'};
|
|
goto ERROR;
|
|
}
|
|
if (!($cgiparams{'NEW_PASSWORD_1'} eq $cgiparams{'NEW_PASSWORD_2'}))
|
|
{
|
|
$errormessage = $tr{'advproxy errmsg passwords different'};
|
|
goto ERROR;
|
|
}
|
|
if (length($cgiparams{'NEW_PASSWORD_1'}) < $proxysettings{'NCSA_MIN_PASS_LEN'})
|
|
{
|
|
$errormessage = $tr{'advproxy errmsg password length 1'}.$proxysettings{'NCSA_MIN_PASS_LEN'}.$tr{'advproxy errmsg password length 2'};
|
|
goto ERROR;
|
|
}
|
|
|
|
# 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;
|
|
undef %cgiparams;
|
|
}
|
|
|
|
ERROR:
|
|
|
|
print "Pragma: no-cache\n";
|
|
print "Cache-control: no-cache\n";
|
|
print "Connection: close\n";
|
|
print "Content-type: text/html\n\n";
|
|
|
|
print <<END
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
|
<title></title>
|
|
</head>
|
|
|
|
<body bgcolor="#FFFFFF">
|
|
|
|
<center>
|
|
|
|
<form method='post' action='$ENV{'SCRIPT_NAME'}'>
|
|
|
|
<table width="80%" cellspacing="10" cellpadding="5">
|
|
|
|
<tr>
|
|
<td bgcolor="#FFFFFF" align="center">
|
|
<table width="100%" cellspacing="10" cellpadding="10" bordercolor="#9A9A9A" border="1">
|
|
<tr>
|
|
<td nowrap bgcolor="#993333" align="center" >
|
|
<font face="trebuchet ms, helvetica, sans-serif" color="#FFFFFF" size="4">
|
|
<b>$tr{'advproxy chgwebpwd change web password'}</b>
|
|
</font>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">
|
|
<table width="50%" cellspacing="7" cellpadding="7">
|
|
<tr>
|
|
<td nowrap bgcolor="#FFFFFF" align="left">
|
|
<font face="trebuchet ms, helvetica, sans-serif" color="#666666" size="2">
|
|
<b>$tr{'advproxy chgwebpwd username'}:</b>
|
|
</font>
|
|
</td>
|
|
<td ><input type="text" name="USERNAME" value="$cgiparams{'USERNAME'}" size="30"></td>
|
|
</tr>
|
|
<tr>
|
|
<td nowrap bgcolor="#FFFFFF" align="left">
|
|
<font face="trebuchet ms, helvetica, sans-serif" color="#666666" size="2">
|
|
<b>$tr{'advproxy chgwebpwd old password'}:</b>
|
|
</font>
|
|
</td>
|
|
<td><input type="password" name="OLD_PASSWORD" value="$cgiparams{'OLD_PASSWORD'}" size="30"></td>
|
|
</tr>
|
|
<tr>
|
|
<td nowrap bgcolor="#FFFFFF" align="left">
|
|
<font face="trebuchet ms, helvetica, sans-serif" color="#666666" size="2">
|
|
<b>$tr{'advproxy chgwebpwd new password'}:</b>
|
|
</font>
|
|
</td>
|
|
<td><input type="password" name="NEW_PASSWORD_1" value="$cgiparams{'NEW_PASSWORD_1'}" size="30"></td>
|
|
</tr>
|
|
<tr>
|
|
<td nowrap bgcolor="#FFFFFF" align="left">
|
|
<font face="trebuchet ms, helvetica, sans-serif" color="#666666" size="2">
|
|
<b>$tr{'advproxy chgwebpwd new password confirm'}:</b>
|
|
</font>
|
|
</td>
|
|
<td><input type="password" name="NEW_PASSWORD_2" value="$cgiparams{'NEW_PASSWORD_2'}" size="30"></td>
|
|
</tr>
|
|
</table>
|
|
<table width="100%" cellspacing="7" cellpadding="7">
|
|
<tr>
|
|
<td align="center"><br><input type='submit' name='SUBMIT' value="$tr{'advproxy chgwebpwd change password'}"></td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
END
|
|
;
|
|
|
|
if ($errormessage)
|
|
{
|
|
print <<END
|
|
<tr>
|
|
<td nowrap bgcolor="#FF0000" align="center">
|
|
<font face="trebuchet ms, helvetica, sans-serif" color="#FFFFFF" size="2">
|
|
<b>$tr{'advproxy chgwebpwd ERROR'}</b> $errormessage
|
|
</font>
|
|
</td>
|
|
</tr>
|
|
END
|
|
;
|
|
}
|
|
|
|
if ($success)
|
|
{
|
|
print <<END
|
|
<tr>
|
|
<td nowrap bgcolor="#00C000" align="center">
|
|
<font face="trebuchet ms, helvetica, sans-serif" color="#FFFFFF" size="2">
|
|
<b>$tr{'advproxy chgwebpwd SUCCESS'}</b> $tr{'advproxy errmsg change success'}
|
|
</font>
|
|
</td>
|
|
</tr>
|
|
END
|
|
;
|
|
}
|
|
|
|
|
|
print <<END
|
|
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
</table>
|
|
|
|
</form>
|
|
|
|
</center>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
END
|
|
;
|
|
|
|
# -------------------------------------------------------------------
|
|
|
|
sub readhash
|
|
{
|
|
my $filename = $_[0];
|
|
my $hash = $_[1];
|
|
my ($var, $val);
|
|
|
|
if (-e $filename)
|
|
{
|
|
open(FILE, $filename) or die "Unable to read file $filename";
|
|
while (<FILE>)
|
|
{
|
|
chop;
|
|
($var, $val) = split /=/, $_, 2;
|
|
if ($var)
|
|
{
|
|
$val =~ s/^\'//g;
|
|
$val =~ s/\'$//g;
|
|
|
|
# Untaint variables read from hash
|
|
$var =~ /([A-Za-z0-9_-]*)/; $var = $1;
|
|
$val =~ /([\w\W]*)/; $val = $1;
|
|
$hash->{$var} = $val;
|
|
}
|
|
}
|
|
close FILE;
|
|
}
|
|
}
|
|
|
|
# -------------------------------------------------------------------
|
|
|
|
sub getcgihash
|
|
{
|
|
my ($hash, $params) = @_;
|
|
my $cgi = CGI->new ();
|
|
return if ($ENV{'REQUEST_METHOD'} ne 'POST');
|
|
if (!$params->{'wantfile'}) {
|
|
$CGI::DISABLE_UPLOADS = 1;
|
|
$CGI::POST_MAX = 512 * 1024;
|
|
} else {
|
|
$CGI::POST_MAX = 10 * 1024 * 1024;
|
|
}
|
|
|
|
$cgi->referer() =~ m/^https?\:\/\/([^\/]+)/;
|
|
my $referer = $1;
|
|
$cgi->url() =~ m/^https?\:\/\/([^\/]+)/;
|
|
my $servername = $1;
|
|
return if ($referer ne $servername);
|
|
|
|
### Modified for getting multi-vars, split by |
|
|
%temp = $cgi->Vars();
|
|
foreach my $key (keys %temp) {
|
|
$hash->{$key} = $temp{$key};
|
|
$hash->{$key} =~ s/\0/|/g;
|
|
$hash->{$key} =~ s/^\s*(.*?)\s*$/$1/;
|
|
}
|
|
|
|
if (($params->{'wantfile'})&&($params->{'filevar'})) {
|
|
$hash->{$params->{'filevar'}} = $cgi->upload
|
|
($params->{'filevar'});
|
|
}
|
|
return;
|
|
}
|
|
|
|
# -------------------------------------------------------------------
|