????
Current Path : /scripts/ |
Current File : //scripts/phpextensionmgr |
#!/usr/local/cpanel/3rdparty/bin/perl # cpanel - scripts/phpextensionmgr Copyright 2014 cPanel, Inc. # All rights Reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited use strict; use warnings; use Getopt::Long; use Pod::Usage; use Cpanel::YAML::Syck (); use Cpanel::CachedDataStore (); use Cpanel::Config::LoadCpConf (); use Cpanel::Config::CpConfGuard (); use Cpanel::Config::Httpd::EA4 (); use Cpanel::Config::Sources (); use Cpanel::ConfigFiles::Apache (); use Cpanel::HttpUtils::ApRestart::BgSafe (); use Cpanel::Crypt::GPG::Settings (); use Cpanel::HttpRequest (); use Cpanel::Logger (); use Cpanel::OSSys (); use Cpanel::SafeDir::RM (); use Cpanel::SafeRun::Errors (); use Cpanel::Sync::Digest (); my $help; my $prefix; my $action; my $extension; my $local_tarball; # From cmd line, for testing new tarball, circumvents tarball download. Warning: bypasses md5 sum check # This script does not work properly with EA4 right now if ( Cpanel::Config::Httpd::EA4::is_ea4() ) { die "This script is not supported in EasyApache 4 at this time\n"; } my $apacheconf = Cpanel::ConfigFiles::Apache->new(); my %extensions = ( 'Zendopt' => 'binary', 'PHPSuHosin' => 'source', 'IonCubeLoader' => 'binary', 'SourceGuardian' => 'binary', 'EAccelerator' => 'source', 'Xcache' => 'source', ); GetOptions( 'help' => \$help, 'prefix=s' => \$prefix, 'local-tarball=s' => \$local_tarball ); $action = shift || ( $help = 1 ); $action = lc($action); $extension = shift || ( $help = 1 ); if ( $action eq 'list' ) { print "Available Extensions:\n"; print join( "\n", keys %extensions ); print "\n"; exit; } elsif ( !$help && $action ne 'status' && $action ne 'install' && $action ne 'uninstall' ) { print "Invalid action specified\n"; $help = 1; } pod2usage(1) if $help; if ( $> != 0 ) { print "This script must be run by the root user.\n"; exit 1; } # check that extension is in list my $found = 0; foreach my $avail_ext ( keys %extensions ) { if ( lc($extension) eq lc($avail_ext) ) { $extension = $avail_ext; $found = 1; last; } } unless ($found) { print "Extension ${extension} is not supported\n"; exit 1; } if ( $prefix && $prefix =~ m{(?:/usr/local/cpanel/3rdparty|/var/cpanel/3rdparty)} ) { my $deprecate_msg = qq{The prefix $prefix is deprecated. Please see the documentation at: https://go.cpanel.net/1136phpextensionmgr}; print $deprecate_msg, "\n"; Cpanel::Logger->new->deprecated($deprecate_msg); if ( $extension !~ m{(?:IonCubeLoader|Zendopt|SourceGuardian)} ) { my $unsupported_msg = "The extension `$extension' is not supported for internal PHP."; local $SIG{__DIE__} = sub { exit 1; }; Cpanel::Logger->new->die($unsupported_msg); } my %extensions_cpcfg = (qw/ Zendopt zend IonCubeLoader ioncube SourceGuardian sourceguardian /); my $cpconf_ref = Cpanel::Config::LoadCpConf::loadcpconf(); my %php_loaders = map { ( $_ => 1 ) } split( /,/, $cpconf_ref->{'phploader'} ); # Verify that extention to be installed is not already configured my @extensions_cpcfg = values(%extensions_cpcfg); # Get the proper value needed for $cpconf_ref my $extension_cpcfg = $extensions_cpcfg{$extension}; if ( $action eq 'install' ) { if ( $php_loaders{$extension_cpcfg} ) { print "$extension_cpcfg is already enabled for internal PHP\n"; exit 3; } $php_loaders{$extension_cpcfg} = 1; } elsif ( $action eq 'uninstall' ) { if ( !$php_loaders{$extension_cpcfg} ) { print "$extension_cpcfg is not enabled for internal PHP\n"; exit 3; } delete $php_loaders{$extension_cpcfg}; } elsif ( $action eq 'status' ) { print 'Installed extensions for internal PHP: ' . $cpconf_ref->{'phploader'} . "\n"; exit 2; } else { # Should never be able to get here. die("Unsupported action"); } # Assure none is only saved if nothing else is selected. delete $php_loaders{'none'}; if ( !%php_loaders ) { $php_loaders{'none'} = 1; } # Write cpanel.config require Cpanel::Config::CpConfGuard; my $cpconf_guard = Cpanel::Config::CpConfGuard->new() or die("Failed to load cpanel config file: $!"); $cpconf_guard->{'data'}->{'phploader'} = join( ',', keys(%php_loaders) ); $cpconf_guard->save(); if ( exists $php_loaders{'sourceguardian'} ) { if ( -e '/var/cpanel/disablesourceguardian' ) { unlink '/var/cpanel/disablesourceguardian'; } } # Update the php.ini with to use extensions system '/usr/local/cpanel/bin/checkphpini'; system '/usr/local/cpanel/bin/install_php_inis'; print "$extension_cpcfg has been " . ( $action eq 'install' ? 'installed' : 'uninstalled' ) . "\n"; exit 2; } my $tarball_filename = $local_tarball || get_tarball_filename( $extension, \%extensions ); # setup working directory my $home = -d '/usr/home' ? '/usr/home' : '/home'; mkdir $home . '/cpeasyapache' unless -d $home . '/cpeasyapache'; mkdir $home . '/cpeasyapache/phpextensions' unless -d $home . '/cpeasyapache/phpextensions'; unless ( -d $home . '/cpeasyapache/phpextensions' ) { die "Could not mkdir $home/cpeasyapache/phpextensions"; } chdir $home . '/cpeasyapache/phpextensions' or die "Could not chdir to $home/cpeasyapache/phpextensions: $!"; # download tarball download_tarball_if_needed($tarball_filename) if !$local_tarball; # make certain php.ini is available for installations if ( $action eq 'install' ) { if ($prefix) { system( '/usr/local/cpanel/scripts/updatephpconf', $prefix ); } else { system('/usr/local/cpanel/scripts/updatephpconf'); } } # untar my $file_list = Cpanel::SafeRun::Errors::saferunnoerror( 'tar', 'tfz', $tarball_filename ); my @FILES = split( /\n/, $file_list, 2 ); my $extension_dir = $FILES[0]; unless ( $extension_dir =~ m{[^\./]+[^/]*/?} ) { die "Extension directory in downloaded tarball appears to be invalid: $extension_dir"; } if ( -d $extension_dir ) { # unlink the exististing directory Cpanel::SafeDir::RM::safermdir($extension_dir); } Cpanel::SafeRun::Errors::saferunallerrors( 'tar', 'xzf', $tarball_filename ); # cd chdir $extension_dir or die "Could not chdir into $extension_dir: $!"; # execute ./cpanel-install (prefix) my @cmd = (); my $maybe_restart = 0; if ( $action eq 'install' ) { print "Installing $extension\n"; @cmd = ('./cpanel-install'); $maybe_restart = 1; } elsif ( $action eq 'uninstall' ) { print "Uninstalling $extension\n"; @cmd = ('./cpanel-uninstall'); $maybe_restart = 1; } else { print "Determining status of $extension\n"; @cmd = ('./cpanel-status'); } push @cmd, $prefix if $prefix; system(@cmd); if ($maybe_restart) { my $phpopts = Cpanel::CachedDataStore::fetch_ref( $apacheconf->file_conf_php_conf() . '.yaml' ); $phpopts = { 'phpversion' => undef } unless $phpopts; # If phpversion isn't set, the default is that php5 is dso. if ( !$phpopts->{'phpversion'} || $phpopts->{'php5'} eq 'dso' || $phpopts->{'php4'} eq 'dso' ) { Cpanel::HttpUtils::ApRestart::BgSafe::restart(); } } # cleanup? sub get_tarball_filename { my $extension = shift; my $extensions_ref = shift; my $filename = $extension . '.pm.tar.gz'; if ( $extensions_ref->{$extension} eq 'source' ) { return $filename; } my ( $system, $release, $machine ) = ( Cpanel::OSSys::uname() )[ 0, 2, 4 ]; $system = 'linux'; $release = 'generic'; if ( $machine =~ /64/i ) { $machine = '64'; } else { $machine = '32'; } return $filename . ".$system-$release-$machine"; } sub download_tarball_if_needed { my $tarball_filename = shift; my $httpClient = Cpanel::HttpRequest->new( 'hideOutput' => 0 ); if ( !-e 'targz.yaml' || ( stat(_) )[9] < time() - 24 * 60 * 60 ) { print "Updating digest list\n"; my $sources = Cpanel::Config::Sources::loadcpsources(); # Download signed targz.yaml $httpClient->download( 'http://' . $sources->{'HTTPUPDATE'} . "/cpanelsync/easy/targz.yaml", 'targz.yaml', 1 ); die "Could not download targz.yaml" unless -e 'targz.yaml'; system('touch targz.yaml'); # make sure mtime is updated } my ( $targz_md5s, $targz_sha512s ) = eval { YAML::Syck::LoadFile('targz.yaml'); }; if ( !( $targz_md5s || $targz_sha512s ) ) { die "Couldn't load targz.yaml: $!"; } my $tarball_ea_dir = '/var/cpanel/perl/easy/Cpanel/Easy/'; my $tarball_ea_fullpath = $tarball_ea_dir . $tarball_filename; my %tarball_digests = ( md5 => $targz_md5s->{$tarball_ea_fullpath}, sha512 => $targz_sha512s->{$tarball_ea_fullpath}, ); if ( ( -e $tarball_filename ) && _digest_file_match( \%tarball_digests, $tarball_filename ) ) { # Local copy available...good to go. return; } elsif ( ( -e $tarball_ea_fullpath ) && _digest_file_match( \%tarball_digests, $tarball_ea_fullpath ) ) { # EA3 copy available unlink $tarball_filename if ( -e $tarball_filename ); system( 'cp', $tarball_ea_fullpath, $tarball_filename ); } else { print "Downloading tarball for $extension\n"; my $sources = Cpanel::Config::Sources::loadcpsources(); $httpClient->download( 'http://' . $sources->{'HTTPUPDATE'} . "/cpanelsync/easy/targz/Cpanel/Easy/${tarball_filename}", $tarball_filename ); die "Could not download $tarball_filename" unless -e $tarball_filename; die "Failed to match a valid digest for $tarball_filename" if ( !_digest_file_match( \%tarball_digests, $tarball_filename ) ); } } sub _digest_file_match { my ( $digests_r, $file ) = @_; for my $algo ( Cpanel::Crypt::GPG::Settings::allowed_digest_algorithms() ) { my $expected = $digests_r->{$algo}; my $real = Cpanel::Sync::Digest::digest( $file, { algo => $algo } ); if ( defined($expected) && ( $real eq $expected ) ) { return 1; } } return 0; } __END__ =head1 NAME phpextensionmgr - Installer/Uninstaller for common PHP extensions =head1 SYNOPSIS phpextensionmgr [options] [action] [extension] Options: --help Help message --prefix Installation prefix for PHP (normally /usr/local) Actions: install Install or update the extension uninstall Uninstall the extension status Display the installation status of the extension list Show available extensions =cut