| Server IP : 89.117.53.150 / Your IP : 216.73.216.11 Web Server : Apache System : Linux server2.hostofiraq.site 5.15.0-186-generic #196-Ubuntu SMP Sat Jun 20 16:09:34 UTC 2026 x86_64 User : iscmbt-kufa-atu ( 1014) PHP Version : 8.2.32 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /usr/share/usermin/authentic-theme/ |
Upload File : |
# login-lib-funcs.pl
# Login library reusable functions
use strict;
use warnings;
no warnings 'uninitialized';
our (%in, %gconfig, $root_directory, $config_directory, %tconfig, %theme_text);
our ($miniserv, $bg, $webprefix, $textbox_attrs, $hostname);
# get_secure_cookie()
# Returns the secure cookie string
sub get_secure_cookie
{
my $secook = lc(get_env('https')) eq 'on' ? "; secure" : "";
$secook .= "; httpOnly" if (!$miniserv->{'no_httponly'});
return $secook;
}
# get_banner_auth_headers()
# Returns headers for the login banner
sub get_banner_auth_headers
{
my $secook = get_secure_cookie();
my @headers;
push(@headers, ["Set-Cookie", "banner=1; path=/$secook"]);
return \@headers;
}
# print_banner()
# Prints the login banner
sub print_banner
{
&PrintHeader(&get_charset(), undef, get_banner_auth_headers());
print ui_tag_start('html',
{ 'class' => 'session_login', 'data-bgs' => $bg });
embed_login_head();
print ui_tag_start('body',
{ 'class' => 'session_login', $tconfig{'inbody'} => undef });
embed_overlay_prebody();
print ui_tag_start('div',
{ 'class' => 'form-signin-banner container session_login
alert alert-danger', 'data-dcontainer' => 1 });
print ui_icon('exclamation-triangle', { 'class' => 'fa-3x' });
print ui_br(), ui_br();
my $banner = &read_file_contents($gconfig{'loginbanner'});
my $page = $gconfig{'loginpage'} || $in{'page'} || $webprefix || '/';
$page = &filter_javascript($page);
$banner =~ s/LOGINURL/$page/g;
print "$banner\n";
print ui_tag_end('div');
print ui_tag_end('body');
print ui_tag_end('html');
}
# get_login_auth_headers()
# Returns headers for the login page
sub get_login_auth_headers
{
my $sidname = $miniserv->{'sidname'} || "sid";
my $secook = get_secure_cookie();
my @headers;
push(@headers, ["Auth-type", "auth-required=1"]);
push(@headers, ["Set-Cookie", "banner=0; path=/$secook"])
if ($gconfig{'loginbanner'});
push(@headers, ["Set-Cookie", "$sidname=x; path=/$secook"])
if ($in{'logout'});
push(@headers, ["Set-Cookie", "redirect=1; path=/$secook"]);
push(@headers, ["Set-Cookie", "testing=1; path=/$secook"]);
return \@headers;
}
# print_login_start($type)
# Prints the start of the login page
sub print_login_start
{
my $type = shift;
my $class = 'session_login';
$class .= ' pam_login' if ($type eq 'pam');
# Print the standard header
&PrintHeader(&get_charset(), undef, get_login_auth_headers());
# Print the HTML header
print ui_tag_start('html', { 'class' => $class, 'data-bgs' => $bg });
embed_login_head();
print ui_tag_start('body', { 'class' => $class, $tconfig{'inbody'} => undef });
embed_overlay_prebody();
# Print the container HTML
print ui_tag_start('div',
{ 'class' => "container $class", 'data-dcontainer' => 1 });
# Print alert if bundled SSL cert is used
if (&miniserv_using_default_cert()) {
print ui_alert(&text('defcert_error', ucfirst(&get_product_name()),
($ENV{'MINISERV_KEYFILE'} || $miniserv->{'keyfile'})),
'warning', undef,
{ 'data-defcert' => 1,
'class' => 'faa-horizontal animated' });
}
# Print success on password reset
if ($in{'returned'}) {
# Password reset successful
print ui_alert($theme_text{'session_pwdsucc'},
'success', ['fa-unlock', $theme_text{'login_success'}],
{ 'class' => 'faa-bounce animated' });
}
# Print alert on failed login
elsif ($in{'failed'}) {
# Two-factor authentication failed
if ($in{'twofactor_msg'}) {
print ui_alert(&theme_text('session_twofailed',
$in{'twofactor_msg'}), 'warning',
undef, { 'data-twofactor' => 1,
'class' => 'faa-horizontal animated' });
}
# Login failed
else {
print ui_alert($theme_text{'theme_xhred_session_failed'},
'warning', undef,
{ 'class' => 'faa-horizontal animated' });
}
}
# Print alert on logout
elsif ($in{'logout'}) {
print ui_alert($theme_text{'session_logout'},
'success', ['fa-sign-out', $theme_text{'login_success'}],
{ 'class' => 'faa-bounce animated' });
}
# Print alert on session timeout
elsif ($in{'timed_out'}) {
print ui_alert(&theme_text('session_timed_out',
int($in{'timed_out'} / 60)),
'warning', ['fa-clock'],
{ 'class' => 'faa-horizontal animated' });
}
}
# print_login_end()
# Prints the end of the login page
sub print_login_end
{
print ui_tag_end('div'); # flipper end
print ui_tag_end('div'); # wrapper end
print ui_tag_end('form'); # form end
print ui_tag_end('div'); # main container end
print ui_tag_end('body');
print ui_tag_end('html');
}
# print_login_prefix(content)
# Prints the login MOTD prefix without changing legacy postfix behavior.
sub print_login_prefix
{
my $content = shift;
return if (!defined($content) || $content !~ /\S/);
if ($content =~ "href") {
print_login_postfix($content);
}
else {
print ui_alert(" ".$content, 'info', ['fa2 fa2-message', '', 1],
{ 'class' => 'login-prefix-alert' });
}
}
# print_login_postfix(type)
# Prints the legacy raw/link post-login element. If the type is "href", it will
# print a properly formatted link to the login page.
sub print_login_postfix
{
my $type = shift;
if ($type =~ "href") {
my $link = get_link($type, 'ugly');
print ui_link_icon($link->[0], $link->[1], "unlock",
{ class => 'warning', target => "_blank" });
}
else {
print "$type\n";
}
}
# print_login_http_warning()
# Prints a warning if the connection is not secure
sub print_login_http_warning
{
return unless ($miniserv->{'ssl'});
# If the connection is not secure, print a warning
if (lc(get_env('https')) ne 'on') {
my $animated_class = 'faa faa-flash faa-slow animated';
my $icon = ui_icon('exclamation-triangle', { 'class' => $animated_class });
my $label = ui_tag('span', $theme_text{'login_notsecure'},
{ 'class' => $animated_class });
my $link = ui_tag('a', "$icon $label",
{ 'href' => "javascript:void(0);",
'class' => 'inherit-color',
'onclick' => "window.location.href = ".
"window.location.href.replace(/^http:/, 'https:'); return false;",
});
print ui_tag('div', $link,
{ 'class' => 'badge badge-danger https-badge', 'data-tooltip' => 1,
'aria-label' => $theme_text{'login_notsecure_desc'} });
}
}
# print_login_logo()
# Prints the Webmin logo and title
sub print_login_logo
{
# Default icon and title
my $product_name = &get_product_name();
local $root_directory = $root_directory;
local $config_directory = $config_directory;
# If request came from Usermin, use its branding instead
if ($in{'return'}) {
$product_name = "usermin";
$root_directory =~ s|/webmin|/usermin|;
$config_directory =~ s|/webmin|/usermin|;
}
my %def_brand = (
file => "$root_directory/images/brand_$product_name.svg",
title => $product_name eq "usermin"
? $theme_text{'theme_xhred_titles_um'}
: $theme_text{'theme_xhred_titles_wm'} );
my %brand = %def_brand;
# Read brand info from file if it exists
my $brand_info = "$config_directory/brand.info";
if (-f $brand_info) {
my %mod_brand;
&read_file($brand_info, \%mod_brand);
# If enabled, use the brand file
if ($mod_brand{'enabled'}) {
%brand = %mod_brand;
# If brand file defined but doesn't exist use default
if (defined($brand{'file'}) && !-f $brand{'file'}) {
%brand = %def_brand;
}
}
}
# Print either logo from file or icon
my $brand_file = $brand{'file'} && -r $brand{'file'} ? $brand{'file'} : undef;
my $title = $brand_file ? undef :
" ". $brand{'title'} // $theme_text{'theme_xhred_titles_wm'};
my $mime;
$mime = &guess_mime_type($brand_file) if ($brand_file);
if ($mime && $mime =~ /^image\//) {
my $image = &read_file_contents($brand_file);
$image =~ s/[\r\n\t ]+/ /g;
print ui_tag('img', undef,
{ 'src' => "data:$mime;base64,".&encode_base64($image),
'alt' => $brand{'title'},
'class' => 'img-title' });
}
else {
print ui_tag('i', undef, { 'class' => $brand{'icon'} // 'wbm-webmin' });
}
# Print the product title
print ui_tag('h2', ui_tag('span', $title),
{ 'class' => 'form-signin-heading' } );
}
# login_username_filter(&in)
# Filters the username returned by the server
sub login_username_filter
{
my ($in) = @_;
my $username = $in->{'failed'};
decode_utf8_ref(\$username);
$username = ($username =~ /^[\p{L}\p{N}\@\_\.\-]+$/) ? $username : undef;
$in->{'failed'} = $username;
}
# login_valid_miniserv_return_port(port)
# Returns true if a miniserv return URL port is valid
sub login_valid_miniserv_return_port
{
my $port = shift;
return defined($port) && $port =~ /^\d+$/ && $port > 0 && $port <= 65535;
}
# login_miniserv_return_port_from_address(value)
# Extracts a port from a miniserv socket/address value
sub login_miniserv_return_port_from_address
{
my ($value) = @_;
return undef if (!defined($value) || $value eq '');
return $1 if ($value =~ /^(\d+)$/);
return $1 if ($value =~ /^\[[^\]]+\]:(\d+)$/);
return $1 if ($value =~ /^[^:]+:(\d+)$/);
return undef;
}
# login_miniserv_return_ports(&miniserv-config)
# Extracts configured miniserv listener ports
sub login_miniserv_return_ports
{
my $miniserv = shift;
my (%seen, @ports);
foreach my $port ($miniserv->{'port'}, $miniserv->{'listen'}) {
if (&login_valid_miniserv_return_port($port) && !$seen{$port}++) {
push(@ports, $port);
}
}
foreach my $sock (split(/\s+/, $miniserv->{'sockets'} || '')) {
my $port = &login_miniserv_return_port_from_address($sock);
if (&login_valid_miniserv_return_port($port) && !$seen{$port}++) {
push(@ports, $port);
}
}
return @ports;
}
# login_valid_return_hostname(host)
# Returns true if an ASCII/punycode return URL hostname has valid labels
sub login_valid_return_hostname
{
my ($host) = @_;
return 0 if (!defined($host) || $host eq '' || $host =~ /\.\./);
foreach my $label (split(/\./, $host, -1)) {
return 0 if ($label eq '' || length($label) > 63);
return 0 if ($label !~ /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/);
}
return 1;
}
# login_normalize_return_host(host, [allow-wildcards])
# Normalizes a hostname from a URL or miniserv SNI key
sub login_normalize_return_host
{
my ($host, $wildcards) = @_;
return undef if (!defined($host));
$host =~ s/^\s+|\s+$//g;
$host =~ s/^\[//;
$host =~ s/\]$//;
$host =~ s/\.$//;
$host = lc($host);
return undef if ($host eq '' || $host =~ /[\x00-\x20\x7f\/\\\@]/);
if ($wildcards && $host =~ s/^\*\.//) {
return undef if (!&login_valid_return_hostname($host));
return "*.$host";
}
return $host if (&login_valid_return_hostname($host));
return $host if ($host =~ /^[a-f0-9:]+$/ && $host =~ /:/);
return undef;
}
# login_miniserv_return_hosts(&miniserv-config)
# Extracts trusted return hostnames from miniserv SNI configuration
sub login_miniserv_return_hosts
{
my $miniserv = shift;
my @hosts;
foreach my $key (keys(%$miniserv)) {
next if ($key !~ /^ipkey_(.+)$/);
push(@hosts, split(/\s*,\s*/, $1));
}
push(@hosts, $miniserv->{'musthost'}) if ($miniserv->{'musthost'});
my $system_host = eval { &get_system_hostname() };
push(@hosts, $system_host) if ($system_host);
return @hosts;
}
# login_add_return_service(&services, ssl, &ports, &hosts)
# Adds an allowed return URL service definition
sub login_add_return_service
{
my ($services, $ssl, $ports, $hosts) = @_;
my (%ports, %hosts, @wildcards);
foreach my $port (@$ports) {
$ports{$port} = 1 if (&login_valid_miniserv_return_port($port));
}
foreach my $host (@$hosts) {
my $norm = &login_normalize_return_host($host, 1);
next if (!$norm);
if ($norm =~ /^\*\.(.+)$/) {
push(@wildcards, $1);
}
else {
$hosts{$norm} = 1;
}
}
return if (!%ports || (!%hosts && !@wildcards));
push(@$services, {
'ssl' => $ssl ? 1 : 0,
'ports' => \%ports,
'hosts' => \%hosts,
'wildcards' => \@wildcards,
});
}
# login_add_miniserv_return_service(&services, &miniserv-config)
# Adds return URLs for a miniserv service
sub login_add_miniserv_return_service
{
my ($services, $miniserv) = @_;
my @ports = &login_miniserv_return_ports($miniserv);
my @hosts = &login_miniserv_return_hosts($miniserv);
&login_add_return_service($services, $miniserv->{'ssl'}, \@ports, \@hosts);
}
# login_add_url_return_service(&services, url)
# Adds return URL service from an explicitly configured URL
sub login_add_url_return_service
{
my ($services, $url) = @_;
return if (!$url);
my ($host, $port, undef, $ssl) =
eval { &parse_http_url($url, undef, undef, undef, undef, undef, undef, 1) };
return if ($@ || !$host || !defined($ssl) || $ssl == 2);
$port ||= $ssl ? 443 : 80;
&login_add_return_service($services, $ssl, [ $port ], [ $host ]);
}
# login_trusted_return_services([base-url])
# Returns trusted Webmin/Usermin return URL services
sub login_trusted_return_services
{
my $baseurl = shift;
my @services;
my @webmin_hosts;
my %miniserv;
if (&get_miniserv_config(\%miniserv)) {
@webmin_hosts = &login_miniserv_return_hosts(\%miniserv);
&login_add_miniserv_return_service(\@services, \%miniserv);
}
&login_add_url_return_service(\@services, $baseurl);
&login_add_url_return_service(\@services, eval { &get_webmin_email_url() });
if (&foreign_check("usermin")) {
eval {
no warnings 'once';
local $main::error_must_die = 1;
&foreign_require("usermin");
my %uminiserv;
&usermin::get_usermin_miniserv_config(\%uminiserv);
if (%uminiserv) {
&login_add_miniserv_return_service(\@services, \%uminiserv);
my @uports = &login_miniserv_return_ports(\%uminiserv);
&login_add_return_service(\@services, $uminiserv{'ssl'},
\@uports, \@webmin_hosts);
&login_add_url_return_service(\@services,
$uminiserv{'redirect_url'});
}
&login_add_url_return_service(\@services,
&usermin::get_usermin_email_url());
};
}
return @services;
}
# login_return_host_allowed(host, &service)
# Returns true if the hostname matches a trusted return URL service
sub login_return_host_allowed
{
my ($host, $service) = @_;
return 1 if ($service->{'hosts'}->{$host});
foreach my $suffix (@{$service->{'wildcards'}}) {
return 1 if ($host =~ /^[^.]+\.\Q$suffix\E$/);
}
return 0;
}
# login_validate_forgot_return_url(return, [base-url])
# Validates password-reset return URLs
sub login_validate_forgot_return_url
{
my ($return, $baseurl) = @_;
return undef if (!defined($return));
$return =~ s/^\s+|\s+$//g;
return undef if ($return eq '' || $return =~ /[\x00-\x1f\x7f\\]/);
if ($return =~ m{^/}) {
return undef if ($return =~ m{^//});
return $return;
}
return undef if ($return !~ m{^https?://}i ||
$return =~ m{^https?://[^/]*\@}i);
my ($host, $port, undef, $ssl) =
eval { &parse_http_url($return, undef, undef, undef, undef, undef, undef, 1) };
return undef if ($@ || !$host || !defined($ssl) || $ssl == 2);
$port ||= $ssl ? 443 : 80;
return undef if (!&login_valid_miniserv_return_port($port));
$host = &login_normalize_return_host($host);
return undef if (!$host);
foreach my $service (&login_trusted_return_services($baseurl)) {
next if ($service->{'ssl'} != ($ssl ? 1 : 0));
next if (!$service->{'ports'}->{$port});
return $return if (&login_return_host_allowed($host, $service));
}
return undef;
}
# login_return_filter(&in)
# Filters password-reset return URLs before they reach the browser
sub login_return_filter
{
my ($in) = @_;
my $return = $in->{'return'};
if (defined($return)) {
$return =~ s/^\s+|\s+$//g;
$return = &login_validate_forgot_return_url($return);
}
$in->{'return'} = $return;
}
# login_params_populate(&in)
# Populates the input data not passed back by the server
sub login_params_populate
{
my ($in) = @_;
if ($gconfig{'forgot_pass'} && !$in->{'failed'}) {
my $request_uri_u = &un_urlize(get_env('request_uri'));
($in->{'forgot'}) = $request_uri_u =~ /[?&]forgot=([A-Fa-f0-9]+)/;
($in->{'username'}) =
$request_uri_u =~ /[?&]username=([\p{L}\p{N}\@\_\.\-]+)/
if ($in->{'forgot'});
($in->{'return'}) = $request_uri_u =~ /[?&]return=([^&]+)/;
($in->{'returned'}) = $request_uri_u =~ /[?&]returned-username=([^&#]*)/;
&login_return_filter($in);
}
}
# print_login_container()
# Prints the login container
sub print_login_container
{
# Print login container wrapper
print ui_tag_start('div', { 'class' => 'session_login_wrapper' });
print ui_tag_start('div',
{ 'class' => "session_login_flipper".
($in{'forgot'} ? ' flipped forgot no-transition' : '') });
# Front side
print ui_tag_start('div', { 'class' => 'session_login_front' });
}
# print_password_reset()
# Prints the password reset inputs
sub print_password_reset
{
# Can reset password and failed or forgot
if ($gconfig{'forgot_pass'}) {
# Back side
my $extra_attrs = $in{'username'} ? {
'data-username' => $in{'username'},
'data-forgot' => $in{'forgot'} } : {};
print ui_tag_start('div',
{ 'class' => 'session_login_back forgot', %{$extra_attrs} });
if($in{'forgot'}) {
print ui_tag_start('p', { 'class' => 'form-signin-paragraph' });
print ui_tag_content(
&theme_text('reset_message',
&html_escape($in{'username'})));
print ui_tag('strong', &html_escape($hostname));
print ui_tag_end('p');
print ui_tag_start('div',
{ 'class' => 'input-group form-group' });
print &ui_password("newpass", undef, 20, 0, undef,
"@{[$textbox_attrs->('off')]} autofocus ".
"data-return='"."e_escape($in{'return'}, "'")."' ".
"placeholder='$theme_text{'session_resetpass1'}'",
'session_login', 1);
print ui_tag_start('span', { 'class' => 'input-group-addon' });
print ui_icon('fa2-account-key');
print ui_tag_end('span');
print ui_tag_end('div');
print ui_tag_start('div',
{ 'class' => 'input-group form-group' });
print &ui_password("newpass2", undef, 20, 0, undef,
"@{[$textbox_attrs->('off')]} ".
"placeholder='$theme_text{'session_resetpass2'}'",
'session_login', 1);
print ui_tag_start('span', { 'class' => 'input-group-addon' });
print ui_icon('key-plus');
print ui_tag_end('span');
print ui_tag_end('div');
print ui_tag_start('div',
{ 'class' => 'form-group form-signin-group' });
print ui_button_icon(
$theme_text{'theme_left_mail_change_password'},
"unlock", { class => "warning", 'data-unlocker' => undef });
print ui_button_icon(
$theme_text{'theme_xhred_global_cancel'},
"fa2-back-in-time", { 'data-flipper' => undef });
print ui_tag_end('div');
print ui_tag_end('div'); # back side end
}
else {
print ui_tag_start('p', { 'class' => 'form-signin-paragraph' });
print ui_tag_content($theme_text{'lost_message'});
print ui_tag_end('p');
print ui_tag_start('div',
{ 'class' => 'input-group form-group' });
print &ui_textbox("forgot", $in{'failed'}, 20, 0, undef,
"@{[$textbox_attrs->()]} ".
"data-return='"."e_escape($in{'return'}, "'")."' ".
"placeholder='$theme_text{'theme_xhred_login_user'}'",
"session_login", 1);
print ui_tag_start('span', { 'class' => 'input-group-addon' });
print ui_icon('user-o');
print ui_tag_end('span');
print ui_tag_end('div');
print ui_tag_start('div',
{ 'class' => 'form-group form-signin-group' });
print ui_button_icon(
$theme_text{'login_recover'}, "fa2-email",
{ class => "success", type => 'submit' });
print ui_button_icon(
$theme_text{'login_back'}, "undo",
{ 'data-flipper' => undef });
print ui_tag_end('div');
}
print ui_tag_end('div'); # back side end
}
}
1;