package Cpanel::Easy::Apache::2_2;

# cpanel - Cpanel/Easy/Apache/2_2.pm              Copyright(c) 2015 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited

# make sure any changes here are reflected in Cpanel::Easy::Apache::get_apache_defaults_text() if necessary

use Cpanel::FileUtils        ();
use Cpanel::Version::Compare ();
use Cpanel::Version::Tiny    ();

use Cpanel::Easy::Apache::Utils::Support ();

our $easyconfig = {
    'name'               => 'Apache 2.2',
    'note'               => 'EOL as of December 2017',
    'support'            => $Cpanel::Easy::Apache::Utils::Support::ENDOFLIFE,
    'hastargz'           => 1,
    'src_cd2'            => 'httpd-2.2',                                        # _apache_versions()
    'version'            => '2.2.34',
    'dryrun_fails_fatal' => 1,
    'depend_fails_fatal' => 1,
    'perl_modules'       => {
        'Digest::SHA1'     => 1,
        'Crypt::PasswdMD5' => 1
    },
    'configure' => {
        '--enable-logio'        => [],
        '--prefix'              => ['/usr/local/apache'],
        '--enable-ssl'          => [],
        '--with-included-apr'   => [],
        '--enable-rewrite'      => [],
        '--enable-suexec'       => [],
        '--with-suexec-logfile' => ['/usr/local/apache/logs/suexec_log'],
        '--with-suexec-caller'  => ['nobody'],
        '--with-suexec-uidmin'  => ['100'],
        '--with-suexec-gidmin'  => ['100'],
        '--with-suexec-docroot' => ['/'],
        '--with-suexec-userdir' => ['public_html'],
        '--with-mpm'            => ['prefork'],
        '--disable-v4-mapped'   => [],
        '--with-crypto'         => [],                                      # this is passed to apr-util
    },
    'modself' => sub {
        my ( $easy, $self_hr ) = @_;

        # Turning off mod_info requires cP 11.52.1.0 or later;
        # versions before get mod_info, so as not to cause potential
        # breakage.
        if ( Cpanel::Version::Compare::compare( $Cpanel::Version::Tiny::VERSION_BUILD, '<', '11.52.1.0' ) ) {
            $self_hr->{'configure'}{'--enable-info'} = [];
        }

        if ( $easy->is_redhat() && $easy->{'getos_releaseversion'} >= 7 ) {
            $self_hr->{'hastargz'}                   = 0;
            $self_hr->{'skip'}                       = 1;
            $self_hr->{'skip_reason'}                = [qq{Apache 2.2 is not available on servers that run CentOS 7. You must adjust your profile to use Apache 2.4 instead.\n\nFor more information, view our Apache documentation (https://go.cpanel.net/ApacheVersions).}];
            $self_hr->{'treat_as_off_while_skipped'} = 1;
        }

        return ( 1, q{Ok} );
    },
    'dryrun' => {
        '0.1' => {
            'name'    => 'Applying patches if any',
            'command' => sub {
                my ($self) = @_;

                my @patches = qw(
                  2_2.OPTIONSBLEED.patch
                  2.2.6-ssl_engine_rand.patch
                  2.2.8_ssl_scache_dbm.patch
                  whmserverstatus.patch
                  safe_conf_defaults.patch
                  suexec_standard.patch
                  mailman_suexec.patch
                  fileprotect_suexec_httpusergroupallow.patch
                  2.2_apachectl_startssl_support.patch
                  apache_2.2_apachectl_ulimit.patch
                  apache_dump_directives.patch
                  2.2_default_user_dir.patch
                  2.2.12-server-listen.patch
                  apache_2.2_bug_47673.patch
                  apache_2.2_external_pcre.patch
                  0001-Patch-suexec-to-allow-userdir-with-FastCGI.patch
                );

                if ( $self->{'cpu_bits'} eq '64' ) {
                    push @patches, 'apache-2_2-64bit.patch';
                }
                if ( $self->has_cloudlinux_support() ) {
                    push @patches, 'apr-2.2-httpd.4.patch';
                }

                my @rc = ( 1, 'Ok' );
                foreach my $patch (@patches) {
                    if ( -e '../cppatch/' . $patch ) {
                        @rc = $self->apply_patch( '../cppatch/' . $patch );
                        return @rc if !$rc[0];
                    }
                }
                return @rc;
            },
        },
        '1' => {
            'name'    => 'Setting permissions on cgi-sys',
            'command' => sub {
                my ($self) = @_;
                chmod 0755, '/usr/local/cpanel/cgi-sys';
                return ( 1, 'Ok' );
            },
        },
        '2' => {
            'name'    => 'Check SSL',
            'command' => sub {
                my ($self) = @_;
                my $openssl_path = $self->get_openssl_prefix( { 'skip_mach' => 1 } );

                if ($openssl_path) {
                    $self->add_to_configure( { '--with-ssl' => $openssl_path } );
                }
                return ( 1, 'Ok' );
            },
        },
    },
    'step' => {
        '0' => {
            'name'    => 'Setting up cp identifier',
            'command' => sub {
                my ($self) = @_;
                my %err;

                my $rc = Cpanel::FileUtils::regex_rep_file(
                    'server/main.c',
                    { qr{^(\s*)(printf[(]["]Server\s+built[:].*)$} => q{$1$2\n$1} . q{printf("Cpanel::Easy::Apache v%s rev%s\\\n", } . qq{"$self->{'version'}", "$self->{'revision'}");}, }, \%err,
                );

                return ( 0, 'Could not patch for cp identifier' ) if !$rc;
                return ( 1, 'ok' );
            },
        },
        '0.01' => {
            'name'    => 'Check PCRE',
            'command' => sub {
                my $self = shift;
                my ( $path, @text ) = $self->get_path_installed('Cpanel::Easy::OptLib::pcre');
                if ($path) {
                    $self->{'__'}{'pcre_path'} = $path;
                    $self->add_to_configure( { '--with-pcre' => [$path] } );

                    # we need to additionally affect LD_LIBRARY_PATH, this change affects %ENV outside of this local scope
                    $ENV{'LD_LIBRARY_PATH'} = ( exists $ENV{'LD_LIBRARY_PATH'} and $ENV{'LD_LIBRARY_PATH'} ) ? qq($path/lib:$ENV{'LD_LIBRARY_PATH'}) : qq($path/lib);    # wrapped qq's in () for clarity
                }
                return ( $path, @text );
            },
        },
        '0.1' => {
            'name'    => 'Configure',
            'command' => sub {
                my ($self) = @_;

                if ( -d '/usr/kerberos/include' && $ENV{'CFLAGS'} !~ m{/usr/kerberos/include} ) {
                    $ENV{'CFLAGS'} .= ' -I/usr/kerberos/include';
                }

                $self->add_to_configure( $self->get_raw_opts_if_any('Apache2_2') );

                $self->print_configure();
                local $ENV{'CFLAGS'}   = $ENV{'CFLAGS'};
                local $ENV{'LDFLAGS'}  = $ENV{'LDFLAGS'};
                local $ENV{'CPPFLAGS'} = $ENV{'CPPFLAGS'};

                # 64 bit specific
                $ENV{'LDFLAGS'} = $ENV{'LDFLAGS'} . ' -L/usr/lib64'    if ( $self->{'cpu_bits'} eq '64' );
                $ENV{'CFLAGS'}  = $ENV{'CFLAGS'} . ' -m64 -fPIC -DPIC' if ( $self->{'cpu_bits'} eq '64' );

                # Disable SNI support
                # $ENV{'CFLAGS'} = $ENV{'CFLAGS'} . ' -DOPENSSL_NO_TLSEXT=1';

                # Custom openssl.  Only the opt LDFLAGS are required for most versions of 2.2.
                # kerberos added for bug in 2.2.10   https://issues.apache.org/bugzilla/show_bug.cgi?id=46168
                if ( $self->get_openssl_prefix( { 'skip_mach' => 1 } ) eq '/opt/openssl' ) {
                    $ENV{'LDFLAGS'} = '-L/opt/openssl/lib -Wl,-R/opt/openssl/lib ' . $ENV{'LDFLAGS'};
                }
                elsif ( -d '/usr/kerberos/lib64' && $ENV{'LDFLAGS'} !~ m{/usr/kerberos/lib64} ) {
                    $ENV{'LDFLAGS'} .= ' -L/usr/kerberos/lib64';
                }
                elsif ( -d '/usr/kerberos/lib' && $ENV{'LDFLAGS'} !~ m{/usr/kerberos/lib} ) {
                    $ENV{'LDFLAGS'} .= ' -L/usr/kerberos/lib';
                }

                return $self->run_system_cmd_returnable( [ './configure', $self->get_configure_as_array() ] );
            },
        },
        '1' => {
            'name'    => 'Making Apache 2.2',
            'command' => sub {
                my ($self) = @_;
                $self->hook_script('/usr/local/cpanel/scripts/before_apache_make');
                my @cmd = ( 'make', @{ $self->get_make_options() } );
                return $self->run_system_cmd_returnable( [@cmd] );
            },
        },
        '2' => {
            'name'    => 'Installing Apache 2.2',
            'command' => sub {
                my ($self) = @_;
                return $self->apache_make_install();
            }
        },
        '4' => {
            'name'    => 'APXSing mod_bwlimited',
            'command' => sub {
                my ($self) = @_;

                return $self->run_system_cmd_returnable( [ qw(/usr/local/apache/bin/apxs -i -a -c), '../mod_bwlimited.c' ] );
            },
        },
        '4.5' => {
            'name'    => 'APXSing mod_disable_suexec',
            'command' => sub {
                my ($self) = @_;

                return $self->run_system_cmd_returnable( [ qw(/usr/local/apache/bin/apxs -i -c), '../mod_disable_suexec.c' ] );
            },
        },
        '4.7' => {
            'name'    => 'APXSing mod_hostinglimits',
            'command' => sub {
                my $self = shift;
                return $self->cloudlinux_update();
            },
        },
        '4.8' => {
            'name'    => 'Activate modules in alternate conf file',
            'command' => sub {
                my ($self) = @_;
                my $alt_conf = $self->{'_'}{'httpd.conf-make_install_created'};
                if ( -e $alt_conf ) {
                    open my $alt_conf_fh, '+<', $alt_conf || return ( 0, q{Could not open '[_1]' for read/write: [_2]}, $alt_conf, $! );
                    my @HTTP_CONF = <$alt_conf_fh>;
                    unshift @HTTP_CONF, "LoadModule bwlimited_module modules/mod_bwlimited.so\n";
                    seek( $alt_conf_fh, 0, 0 );
                    print $alt_conf_fh @HTTP_CONF;
                    truncate( $alt_conf_fh, tell($alt_conf_fh) );
                    close $alt_conf_fh;
                    return ( 1, 'Ok' );
                }
                return ( 0, q{Could not locate [_1]}, $alt_conf );
            },
        },
        '4.85' => {
            'name'    => 'Check for MPMItk',
            'command' => sub {
                my ($self) = @_;
                if ( $self->get_ns_value_from_profile( 'Cpanel::Easy::Apache::MPMItk', $self->{'working_profile'} ) ) {

                    # Update the PHP configuration YAML file
                    my $php_yaml = '/usr/local/apache/conf/php.conf.yaml';
                    if ( -e $php_yaml ) {
                        my $conf = Cpanel::CachedDataStore::fetch_ref($php_yaml);
                        return ( 0, q{Could not read [_1]}, $php_yaml ) unless $conf;
                        $conf->{'suexec'} = 0;
                        Cpanel::CachedDataStore::store_ref( $php_yaml, $conf );
                    }

                    # Disable the suEXEC binary
                    if ( -e '/usr/local/apache/bin/suexec' ) {
                        unlink '/usr/local/apache/bin/suexec.disable' if ( -e '/usr/local/apache/bin/suexec.disable' );
                        rename( '/usr/local/apache/bin/suexec', '/usr/local/apache/bin/suexec.disable' )
                          || return ( 0, q{Could not rename suexec} );
                        chmod( oct(755), '/usr/local/apache/bin/suexec.disable' );
                    }

                    # Load the mod_disable_suexec module
                    $self->ensure_loadmodule_in_httpdconf( 'disable_suexec', 'mod_disable_suexec.so' );
                }
                return ( 1, 'Ok' );
            },
        },
        '4.9' => {
            'name'    => 'Check proxydomains settings',
            'command' => sub {
                my $self = shift;
                return $self->proxydomains_configuration();
            },
        },
        '5' => {
            'name'    => 'Removing invalid User and Group directive',
            'command' => sub {
                my ($self) = @_;
                my @conf_files = ( $self->_get_main_httpd_conf() );
                if ( $self->{'trying_previous_httpd_conf'} && -e $self->{'_'}{'httpd.conf-make_install_created'} ) {
                    push @conf_files, $self->{'_'}{'httpd.conf-make_install_created'};
                }

                my @rc = ();
                foreach my $conf_file (@conf_files) {
                    @rc = $self->strip_apache_directive( $conf_file, 'User ', 'Group ' );
                    return @rc unless $rc[0];
                }
                return @rc;
            },
        },

        # 'modify_later_easy-config_hr' phpasuser starts at 6.1
        # 'modify_later_easy-config_hr' fastcgi starts at 8.1

    },
};

1;
