KGRKJGETMRETU895U-589TY5MIGM5JGB5SDFESFREWTGR54TY
Server : Apache
System : Linux cs317.bluehost.com 4.19.286-203.ELK.el7.x86_64 #1 SMP Wed Jun 14 04:33:55 CDT 2023 x86_64
User : andertr9 ( 1047)
PHP Version : 8.2.18
Disable Function : NONE
Directory :  /cpanel_installer/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //cpanel_installer/CpanelGPG.pm
package CpanelGPG;

# cpanel - installd/CpanelGPG.pm                   Copyright 2021 cPanel, L.L.C.
#                                                           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 Common       ();    # fetch_url_to_file
use CpanelConfig ();    # read_config
use CpanelLogger;

use constant GPG_HOMEDIR => '/var/cpanel/.gpgtmpdir';
use constant PUBLIC_KEYS => {
    'release'     => 'cPanelPublicKey.asc',
    'development' => 'cPanelDevelopmentKey.asc',
};

use constant GPG_KEYRINGS => {
    'release'     => ['release'],
    'development' => [ 'release', 'development' ],
};

use constant SECURE_DOWNLOADS => 'https://securedownloads.cpanel.net/';

sub _create_gpg_homedir {
    mkdir( GPG_HOMEDIR, 0700 ) if !-e GPG_HOMEDIR;
    return;
}

my $gpg_bin;

sub gpg_bin {

    return $gpg_bin if $gpg_bin;

    for my $bin (qw(/usr/bin/gpg /bin/gpg /usr/local/bin/gpg)) {
        next if ( !-e $bin );
        next if ( !-x _ );
        next if ( -z _ );
        return $gpg_bin = $bin;
    }

    FATAL("The installation process could not find the gpg binary. Install it to a standard location.");
    return;
}

sub cleanup_gpg_homedir {
    if ( -d GPG_HOMEDIR ) {
        opendir( my $dh, GPG_HOMEDIR );
        my @files = readdir($dh);
        closedir($dh);
        @files = map { GPG_HOMEDIR . "/" . $_ } grep { !/^\.{1,2}/ } @files;
        unlink($_) for @files;
        rmdir(GPG_HOMEDIR);
    }

    return;
}

sub keys_to_download {

    my $config   = CpanelConfig::read_config('/var/cpanel/cpanel.config');
    my $keyrings = GPG_KEYRINGS;

    if ( !defined $config->{'signature_validation'} ) {
        my $mirror = CpanelConfig::get_update_source();

        if ( $mirror =~ /^(?:.*\.dev|qa-build|next)\.cpanel\.net$/ ) {
            return $keyrings->{'development'};
        }
        else {
            return $keyrings->{'release'};
        }
    }
    elsif ( $config->{'signature_validation'} =~ /^Release and (?:Development|Test) Keyrings$/ ) {
        return $keyrings->{'development'};
    }
    else {
        return $keyrings->{'release'};
    }
}

my $gpg_is_setup;

sub fetch_gpg_key_once {

    return if $gpg_is_setup;

    my $pub_keys = PUBLIC_KEYS;
    _create_gpg_homedir();

    foreach my $key ( sort @{ keys_to_download() } ) {
        INFO("Downloading GPG public key, $pub_keys->{$key}");
        my $target = SECURE_DOWNLOADS . $pub_keys->{$key};
        my $dest   = GPG_HOMEDIR . "/" . $pub_keys->{$key};

        Common::fetch_url_to_file( $target, $dest );
        if ( !-e $dest ) {
            FATAL("Could not download GPG public key at '$target'.");
            return;
        }
        INFO("Importing downloaded GPG public key from '$dest'.");
        if ( -x '/bin/apt-key' ) {
            INFO("Adding $dest via apt-key");
            Common::ssystem( '/bin/apt-key', 'add', $dest );
        }
        my $gpg_cmd = gpg_bin() . " -q --homedir " . GPG_HOMEDIR . " --import " . $dest;
        my $output  = `$gpg_cmd 2>&1`;                                                     ## no critic(ProhibitQxAndBackticks)
        if ( $? != 0 ) {
            WARN("Failed to import GPG public key from '$dest': $output");
        }
    }

    $ENV{'CPANEL_BASE_INSTALL_GPG_KEYS_IMPORTED'} = 1;                                     # in v82+ fix-cpanel-perl will skip gpg keyimport if set
    $gpg_is_setup = 1;

    return;
}

sub verify_file {
    my ( $file, $sig, $url ) = @_;

    fetch_gpg_key_once();

    my @gpg_args = (
        '--logger-fd', '1',
        '--status-fd', '1',
        '--homedir',   GPG_HOMEDIR,
        '--verify',    $sig,
        $file,
    );

    # Verify the validity of the GPG signature.
    # Information on these return values can be found in 'doc/DETAILS' in the GnuPG source.

    my ( %notes, $curnote );
    my ( $gpg_out, $success, $error_status );
    my $gpg_pid = IPC::Open3::open3( undef, $gpg_out, undef, gpg_bin(), @gpg_args );

    while ( my $line = readline($gpg_out) ) {
        if ( $line =~ /^\[GNUPG:\] VALIDSIG ([A-F0-9]+) ([0-9]+-[0-9]+-[0-9]+) ([0-9]+) ([A-F0-9]+) ([A-F0-9]+) ([A-F0-9]+) ([A-F0-9]+) ([A-F0-9]+) ([A-F0-9]+) ([A-F0-9]+)$/ ) {
            $success = 1;
        }
        elsif ( $line =~ /^\[GNUPG:\] NOTATION_NAME (.+)$/ ) {
            $curnote         = $1;
            $notes{$curnote} = '';
            $error_status    = 'Probably invalid notation name';
        }
        elsif ( $line =~ /^\[GNUPG:\] NOTATION_DATA (.+)$/ ) {
            $notes{$curnote} .= $1;
            $error_status = 'Probably invalid notation data';
        }
        elsif ( $line =~ /^\[GNUPG:\] BADSIG ([A-F0-9]+) (.+)$/ ) {
            $error_status = "Invalid signature for $file";
        }
        elsif ( $line =~ /^\[GNUPG:\] NO_PUBKEY ([A-F0-9]+)$/ ) {
            $error_status = "Could not find public key ($1) in keychain";
        }
        elsif ( $line =~ /^\[GNUPG:\] NODATA ([A-F0-9]+)$/ ) {
            $error_status = "Could not find a GnuPG signature in the signature file";
        }
    }

    waitpid( $gpg_pid, 0 );

    $error_status ||= "Unknown error from gpg";

    my $finalize_output = sub { return "$_[0] (file:$file, sig:$sig)" };

    if ($success) {
        INFO( $finalize_output->("Valid signature for $file") );
    }
    else {
        FATAL( $finalize_output->($error_status) );
    }

    # At this point, the signature should be valid.
    # We now need to check to see if the filename signature notation is correct.

    $url =~ s/\.bz2$//;

    if ( defined( $notes{'filename@gpg.notations.cpanel.net'} ) ) {
        my $file_note = $notes{'filename@gpg.notations.cpanel.net'};
        if ( $file_note ne $url ) {
            FATAL( $finalize_output->("Filename notation ($file_note) does not match URL ($url)") );
        }
    }
    else {
        FATAL( $finalize_output->("Signature does not contain the expected filename notation") );
    }

    return;
}

1;

Anon7 - 2021