mirror of
https://github.com/webmin/webmin.git
synced 2026-02-09 00:39:57 +00:00
Compare commits
2 Commits
dev/patch-
...
dev/refer-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7231eedf20 | ||
|
|
d69609f49a |
File diff suppressed because one or more lines are too long
153
bin/patch
153
bin/patch
@@ -1,153 +0,0 @@
|
|||||||
#!/usr/bin/env perl
|
|
||||||
# patch - Apply a patch to Webmin core or its modules from GitHub or a local file
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
|
|
||||||
use 5.010;
|
|
||||||
|
|
||||||
use Getopt::Long qw(:config permute pass_through);
|
|
||||||
use Pod::Usage;
|
|
||||||
use File::Basename;
|
|
||||||
use Cwd qw(cwd);
|
|
||||||
|
|
||||||
my %opt;
|
|
||||||
GetOptions(
|
|
||||||
'help|h' => \$opt{'help'},
|
|
||||||
'config|c=s' => \$opt{'config'},
|
|
||||||
);
|
|
||||||
pod2usage(0) if ($opt{'help'});
|
|
||||||
|
|
||||||
# Get Webmin path
|
|
||||||
my $path = cwd;
|
|
||||||
my $lib = "web-lib-funcs.pl";
|
|
||||||
if (!-r "$path/$lib") {
|
|
||||||
$path = dirname(dirname($0));
|
|
||||||
if (!-r "$path/$lib") {
|
|
||||||
$path = $path = Cwd::realpath('..');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Init core
|
|
||||||
my $config_dir = $opt{'config'} || '/etc/webmin';
|
|
||||||
$ENV{'WEBMIN_CONFIG'} = $config_dir;
|
|
||||||
push(@INC, $path);
|
|
||||||
eval 'use WebminCore';
|
|
||||||
init_config();
|
|
||||||
|
|
||||||
# Check if curl is installed
|
|
||||||
if (!has_command('curl')) {
|
|
||||||
print "curl is not installed\n";
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if git is installed
|
|
||||||
if (!has_command('git')) {
|
|
||||||
print "git is not installed\n";
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get patch URL or file
|
|
||||||
my $patch = $ARGV[0];
|
|
||||||
|
|
||||||
# Params check
|
|
||||||
if (!$patch) {
|
|
||||||
pod2usage(0);
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Patch check
|
|
||||||
if ($patch !~ /^https?:\/\//) {
|
|
||||||
if (!-r $patch) {
|
|
||||||
print "Patch file $patch doesn't exist\n";
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elsif ($patch =~ /^https?:\/\/(github|gitlab)\.com/ &&
|
|
||||||
$patch !~ /\.patch$/ && $patch !~ /\.diff$/) {
|
|
||||||
$patch .= '.patch';
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse module name from URL
|
|
||||||
my $module = "";
|
|
||||||
if ($patch =~ m{https://(github|gitlab)\.com/[^/]+/([^/]+)/commit/[^/]+}) {
|
|
||||||
$module = $2;
|
|
||||||
$module = "" if ($2 eq 'webmin');
|
|
||||||
# Special handling for some modules
|
|
||||||
$module = $module =~ /^virtualmin-pro$/ ?
|
|
||||||
'virtual-server/pro' :
|
|
||||||
'virtual-server'
|
|
||||||
if $module =~ /^virtualmin-(gpl|pro)$/;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if module exists
|
|
||||||
if (!-d "$path/$module") {
|
|
||||||
print "Module $module doesn't exist\n";
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Download command or cat patch file
|
|
||||||
my $cmd;
|
|
||||||
if ($patch =~ /^https?:\/\//) {
|
|
||||||
$cmd = "curl -s @{[quotemeta($patch)]}";
|
|
||||||
chdir "$path/$module";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$cmd = "cat @{[quotemeta($patch)]}";
|
|
||||||
}
|
|
||||||
|
|
||||||
# Apply patch using Git
|
|
||||||
my $output = `$cmd 2>&1 | git apply --reject --verbose --whitespace=fix 2>&1`;
|
|
||||||
if ($output !~ /applied patch.*?cleanly/i) {
|
|
||||||
print "Patch failed: $output\n";
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
print "Patch applied successfully to:\n";
|
|
||||||
print " $1\n" while $output =~ /^Applied patch\s+(\S+)/mg;
|
|
||||||
system("$config_dir/restart");
|
|
||||||
|
|
||||||
=pod
|
|
||||||
|
|
||||||
=head1 NAME
|
|
||||||
|
|
||||||
patch
|
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
|
||||||
|
|
||||||
Apply a patch to Webmin core or its modules from GitHub or a local file.
|
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
|
||||||
|
|
||||||
webmin patch patch-url/file
|
|
||||||
|
|
||||||
=head1 OPTIONS
|
|
||||||
|
|
||||||
=over
|
|
||||||
|
|
||||||
=item --help, -h
|
|
||||||
|
|
||||||
Give this help list.
|
|
||||||
|
|
||||||
=item --config, -c
|
|
||||||
|
|
||||||
Specify the full path to the Webmin configuration directory. Defaults to
|
|
||||||
C</etc/webmin>
|
|
||||||
|
|
||||||
Examples of usage:
|
|
||||||
|
|
||||||
Apply a patch from a URL.
|
|
||||||
|
|
||||||
- webmin patch https://github.com/webmin/webmin/commit/e6a2bb15b0.patch
|
|
||||||
|
|
||||||
- webmin patch https://github.com/virtualmin/virtualmin-gpl/commit/f4433153d
|
|
||||||
|
|
||||||
Apply a patch from local file.
|
|
||||||
|
|
||||||
- cd /usr/libexec/webmin/virtual-server/pro &&
|
|
||||||
webmin patch /root/virtualmin-pro/patches/patch-1.patch
|
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
=head1 LICENSE AND COPYRIGHT
|
|
||||||
|
|
||||||
Copyright 2024 Ilia Ross <ilia@virtualmin.com>
|
|
||||||
@@ -107,7 +107,7 @@ if ($product eq "webmin") {
|
|||||||
$size = int(`du -sk $tmp_dir`);
|
$size = int(`du -sk $tmp_dir`);
|
||||||
@deps = ( "perl", "libnet-ssleay-perl", "openssl", "libauthen-pam-perl", "libpam-runtime", "libio-pty-perl", "unzip", "shared-mime-info", "tar", "libdigest-sha-perl", "libdigest-md5-perl", "gzip" );
|
@deps = ( "perl", "libnet-ssleay-perl", "openssl", "libauthen-pam-perl", "libpam-runtime", "libio-pty-perl", "unzip", "shared-mime-info", "tar", "libdigest-sha-perl", "libdigest-md5-perl", "gzip" );
|
||||||
$deps = join(", ", @deps);
|
$deps = join(", ", @deps);
|
||||||
@recommends = ( "libdatetime-perl", "libdatetime-timezone-perl", "libdatetime-locale-perl", "libtime-piece-perl", "libencode-detect-perl", "libtime-hires-perl", "libsocket6-perl", "lynx", "qrencode" );
|
@recommends = ( "libdatetime-perl", "libdatetime-timezone-perl", "libdatetime-locale-perl", "libtime-piece-perl", "libencode-detect-perl", "libtime-hires-perl", "libsocket6-perl", "libthreads-perl", "libthreads-shared-perl", "lynx", "qrencode" );
|
||||||
$recommends = join(", ", @recommends);
|
$recommends = join(", ", @recommends);
|
||||||
open(CONTROL, ">$control_file");
|
open(CONTROL, ">$control_file");
|
||||||
print CONTROL <<EOF;
|
print CONTROL <<EOF;
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ Release: $rel
|
|||||||
Provides: %{name}-%{version} perl(WebminCore)
|
Provides: %{name}-%{version} perl(WebminCore)
|
||||||
Requires(pre): /usr/bin/perl
|
Requires(pre): /usr/bin/perl
|
||||||
Requires: /bin/sh /usr/bin/perl perl(lib) perl(open) perl(Net::SSLeay) perl(Time::Local) perl(Data::Dumper) perl(File::Path) perl(File::Basename) perl(Digest::SHA) perl(Digest::MD5) openssl unzip tar gzip
|
Requires: /bin/sh /usr/bin/perl perl(lib) perl(open) perl(Net::SSLeay) perl(Time::Local) perl(Data::Dumper) perl(File::Path) perl(File::Basename) perl(Digest::SHA) perl(Digest::MD5) openssl unzip tar gzip
|
||||||
Recommends: perl(DateTime) perl(DateTime::TimeZone) perl(DateTime::Locale) perl(Time::Piece) perl(Encode::Detect) perl(Time::HiRes) perl(Socket6) lynx shared-mime-info perl-File-Basename perl-File-Path qrencode
|
Recommends: perl(DateTime) perl(DateTime::TimeZone) perl(DateTime::Locale) perl(Time::Piece) perl(Encode::Detect) perl(Time::HiRes) perl(Socket6) perl(threads) perl(threads::shared) lynx shared-mime-info perl-File-Basename perl-File-Path qrencode
|
||||||
AutoReq: 0
|
AutoReq: 0
|
||||||
License: BSD-3-clause
|
License: BSD-3-clause
|
||||||
Group: System/Tools
|
Group: System/Tools
|
||||||
|
|||||||
@@ -5540,6 +5540,7 @@ my $unsafe_index = $unsafe_index_cgi ||
|
|||||||
&get_module_variable('$unsafe_index_cgi');
|
&get_module_variable('$unsafe_index_cgi');
|
||||||
my $trustvar = $trust_unknown_referers ||
|
my $trustvar = $trust_unknown_referers ||
|
||||||
&get_module_variable('$trust_unknown_referers');
|
&get_module_variable('$trust_unknown_referers');
|
||||||
|
my $unsafe_params = $ENV{'REQUEST_URI'} =~ /xhr/i;
|
||||||
my $trust = 0;
|
my $trust = 0;
|
||||||
if (!$0) {
|
if (!$0) {
|
||||||
# Script name not known
|
# Script name not known
|
||||||
@@ -5555,7 +5556,7 @@ elsif ($ENV{'DISABLE_REFERERS_CHECK'}) {
|
|||||||
}
|
}
|
||||||
elsif (($ENV{'SCRIPT_NAME'} =~ /^\/(index.cgi)?$/ ||
|
elsif (($ENV{'SCRIPT_NAME'} =~ /^\/(index.cgi)?$/ ||
|
||||||
$ENV{'SCRIPT_NAME'} =~ /^\/([a-z0-9\_\-]+)\/(index.cgi)?$/i) &&
|
$ENV{'SCRIPT_NAME'} =~ /^\/([a-z0-9\_\-]+)\/(index.cgi)?$/i) &&
|
||||||
!$unsafe_index) {
|
!$unsafe_index && !$unsafe_params) {
|
||||||
# Script is a module's index.cgi, which is normally safe
|
# Script is a module's index.cgi, which is normally safe
|
||||||
$trust = 1;
|
$trust = 1;
|
||||||
}
|
}
|
||||||
@@ -8010,100 +8011,6 @@ return ref($s) && $s->{'host'} && $s->{'port'} ?
|
|||||||
ref($s) ? "" : "$s.$$";
|
ref($s) ? "" : "$s.$$";
|
||||||
}
|
}
|
||||||
|
|
||||||
=head2 verify_session_id(session-id, [sessiondb], [miniserv])
|
|
||||||
|
|
||||||
Returns the username (or an array with user, last login, and IP address) for the
|
|
||||||
given session (or session hash) ID, or undefined if session ID is invalid.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
|
|
||||||
$sid: The session ID to verify
|
|
||||||
|
|
||||||
$sessiondb: A reference to the session database hash (optional)
|
|
||||||
|
|
||||||
$miniserv: A reference to the miniserv configuration hash (optional)
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
|
|
||||||
In list context: A list containing the user, last activity time, and IP
|
|
||||||
address associated with the session ID.
|
|
||||||
|
|
||||||
In scalar context: The user associated with the session ID.
|
|
||||||
|
|
||||||
If the session ID is not found, returns an empty list in list context
|
|
||||||
or undef in scalar context.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
Retrieve the username associated with the session ID or undef if
|
|
||||||
session is invalid.
|
|
||||||
|
|
||||||
my $user = verify_session_id($main::session_id);
|
|
||||||
Example of return:
|
|
||||||
root
|
|
||||||
|
|
||||||
Retrieve array containing the user, last login, and IP address
|
|
||||||
for given session hash ID or undef if session is invalid.
|
|
||||||
|
|
||||||
my (@user) = verify_session_id('BSRxr6wpF25lqeRinQ/sv0');
|
|
||||||
Example of return:
|
|
||||||
[
|
|
||||||
'root',
|
|
||||||
'1719401071',
|
|
||||||
'10.211.55.2'
|
|
||||||
]
|
|
||||||
|
|
||||||
Retrieve the username associated with the session ID, using given
|
|
||||||
session DB or undef if session is invalid.
|
|
||||||
|
|
||||||
my %sessiondb;
|
|
||||||
dbmopen(%sessiondb, "$var_directory/sessiondb", 0400);
|
|
||||||
my $user = verify_session_id($main::session_id, \%sessiondb);
|
|
||||||
dbmclose(%sessiondb);
|
|
||||||
Example of return:
|
|
||||||
someuser1
|
|
||||||
|
|
||||||
=cut
|
|
||||||
sub verify_session_id
|
|
||||||
{
|
|
||||||
my ($sid, $sessiondb, $miniserv) = @_;
|
|
||||||
my $hashsessionidfunc = \&miniserv::hash_session_id;
|
|
||||||
my %miniserv;
|
|
||||||
if ($miniserv) {
|
|
||||||
# Use provided miniserv configuration
|
|
||||||
%miniserv = %{$miniserv};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
# Load miniserv configuration if not provided
|
|
||||||
&get_miniserv_config(\%miniserv);
|
|
||||||
}
|
|
||||||
my %sessiondb_;
|
|
||||||
if ($sessiondb) {
|
|
||||||
# Use provided session database
|
|
||||||
%sessiondb_ = %{$sessiondb};
|
|
||||||
}
|
|
||||||
elsif (&foreign_available('acl')) {
|
|
||||||
# Use session database using ACL module API
|
|
||||||
&foreign_require("acl");
|
|
||||||
&acl::open_session_db(\%miniserv);
|
|
||||||
$hashsessionidfunc = \&acl::hash_session_id;
|
|
||||||
%sessiondb_ = %acl::sessiondb;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return wantarray ? ( ) : undef;
|
|
||||||
}
|
|
||||||
# Verify given session (hash) ID against the session database
|
|
||||||
foreach my $k (grep { $sessiondb_{$_} } keys %sessiondb_) {
|
|
||||||
if ($k eq $sid ||
|
|
||||||
(defined($hashsessionidfunc) && $k eq $hashsessionidfunc->($sid))) {
|
|
||||||
my ($user, $last, $ip) = split(/\s+/, $sessiondb_{$k});
|
|
||||||
return wantarray ? ($user, $last, $ip) : $user;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Return an empty list or undef if session ID is not found
|
|
||||||
return wantarray ? ( ) : undef;
|
|
||||||
}
|
|
||||||
|
|
||||||
=head2 remote_foreign_require(server, module, file)
|
=head2 remote_foreign_require(server, module, file)
|
||||||
|
|
||||||
Connects to rpc.cgi on a remote webmin server and have it open a session
|
Connects to rpc.cgi on a remote webmin server and have it open a session
|
||||||
|
|||||||
Reference in New Issue
Block a user