#!/usr/bin/perl -w use CGI; $Q = new CGI; $ENV{'PATH'} = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$ENV{'PATH'}"; my %msg = ( ru => { page_title => "Установка BILLmanager", versiondesc => "Выберите версию BILLmanager, которая будет установлена на ваш сервер.", mysqldesc => "Пожалуйста, укажите параметры соединения с базой данных MySQL. Обращаем ваше внимание, что база данных должна быть создана в кодировке UTF8", mysqlhost => "Сервер", mysqldb => "База данных", mysqluser => "Пользователь", mysqlpass => "Пароль", mysqlsock => "Путь до сокета mysql", ahttpdesc => "В целях безопасности, работа с BILLmanager осуществляется по протоколу HTTPS, обеспечивающему безопасную передачу данных. Однако использование HTTPS протокола возможно не всегда. Если ваш сайт не поддерживает HTTPS, то стоит разрешить использовать обычный HTTP протокол.", ahttp => "Разрешить соединение по HTTP протоколу", apassdesc => "Вам необходимо задать пароль администратора BILLmanager. Обязательно запомните его.", apass => "Пароль пользователя admin", apass2 => "Повторите пароль", butinstall => "Установить", installdesc => "Процедура установки BILLmanager может занять продолжительное время. Пожалуйста, запаситесь терпением и не прерывайте процедуру установки.", er_fetch => "Ошибка: На сервере нет ни одной из следующих программ: fetch, wget, curl. Обратитесь к вашему хостинг провайдеру.", er_md5 => "Ошибка: На сервере не найдено программы для проверки контрольной суммы: /sbin/md5 или /usr/bin/md5sum. Обратитесь к вашему хостинг провайдеру.", er_arch => "Ошибка: Не удаётся определить архитектуру сервера.", er_os => "Ошибка: Установка на вашу операционную систему невозможна.", er_mysql => "Ошибка: На сервере не удалось найти команду mysql. Обратитесь к вашему хостинг провайдеру.", er_tar => "Ошибка: На сервере не удалось найти команду tar. Обратитесь к вашему хостинг провайдеру.", er_lic => "Ошибка: Лицензий BILLmanager на ваш IP-адрес %s не существует.", er_version => "Ошибка: Неправильно указана версия BILLmanager.", er_mhost => "Ошибка: Неправильно указана Сервер MySQL.", er_mdb => "Ошибка: Неправильно указана База данных MySQL.", er_muser => "Ошибка: Неправильно указана Пользователь MySQL.", er_mpass => "Ошибка: Неправильно указана Пароль к MySQL.", er_msock => "Ошибка: Неправильно указана Путь до сокета MySQL.", er_mconnect => "Ошибка: Не удалось соединиться с базой данных по указанным вами параметрам.", er_apass => "Ошибка: Не задан пароль пользователя admin.", er_apassconfirm => "Ошибка: Пароль пользователя admin и подтверждение пароля не совпадают.", er_md5sum => "Ошибка: Не прошла проверка контрольной суммы MD5. Вероятно архив BILLmanager скачен некорректно. Пожалуйста, попробуйте еще раз.", er_fopen => "Ошибка: Невозможно открыть файл %s", er_setpasswd => "Ошибка: Невозможно установить пароль пользователя. Ответ системы: %s", }, en => { page_title => "Installing BILLmanager", versiondesc => "Select a BILLmanager version that will be installed on your server.", mysqldesc => "Specify parameters to connect to the MySQL database. Please note, you should use UTF8 encoding to create a database", mysqlhost => "Server", mysqldb => "Database", mysqluser => "User", mysqlpass => "Password", mysqlsock => "MySQL SOCK", ahttpdesc => "For security purposes, work with BILLmanager is provided via an HTTPS protocol that allows secure data transfer. But there may be situations when it is not possible to use HTTPS. If your site does not support HTTPS, use a common HTTP protocol.", ahttp => "Allow connection via HTTP", apassdesc => "Provide a BILLmanager administrator's password. Please, keep it in mind.", apass => "admin password", apass2 => "Re-type the password", butinstall => "Install", installdesc => "It may take long time for the BILLmanager installation process to complete. Please be patient to complete the installation.", er_root => "Error: Please run script as web-site user.", er_fetch => "Error: Failed to find the following programs on the server: fetch, wget, curl. Contact your hosting provider.", er_md5 => "Error: Failed to find the checksum program on the server: /sbin/md5 or /usr/bin/md5sum. Contact your hosting provider.", er_arch => "Error: Cannot determinate the server architecture.", er_os => "Error: Unable to install BILLmanager on your operating system.", er_mysql => "Error: Failed to find a mysql command on the server. Contact your hosting provider.", er_tar => "Error: Failed to find a tar command on the server. Contact your hosting provider.", er_lic => "Error: A BILLmanager license for your IP-address %s does not exist.", er_version => "Error: Incorrect BILLmanager version BILLmanager.", er_mhost => "Error: Incorrect MySQL Server.", er_mdb => "Error: Incorrect MySQL Database.", er_muser => "Error: Incorrect MySQL User.", er_mpass => "Error: Incorrect MySQL Password.", er_msock => "Error: Incorrect MySQL Sock.", er_mconnect => "Error: Failed to connect to a database with specified parameters.", er_apass => "Error: admin password required.", er_apassconfirm => "Error: admin password and confirmation password do not match.", er_md5sum => "Error: Failed to verify the MD5 checksum. The BILLmanager archive might have been downloaded incorrectly. Please try again.", er_fopen => "Error: Failed to open the file %s", er_setpasswd => "Error: Can not set a user password. Response of the system: %s", } ); my %data = (); my $errormsg = ""; my $lang = "en"; if ( exists $ENV{HTTP_ACCEPT_LANGUAGE} && $ENV{HTTP_ACCEPT_LANGUAGE} =~ /ru/i ) { $lang = "ru"; } my $CMD = 0; if ( $#ARGV != -1 ) { $CMD = 1; for my $a ( @ARGV ) { if ( $a =~ /--(\w+)=(.*)/ ) { $data{$1} = $2; } } $data{action} = "install"; use POSIX; if ( &getuid() == 0 ) { &error("er_root"); } } if ( $CMD == 0 && !exists($ENV{HTTP_HOST}) ) { &printCmdHelp(); } if ( $CMD == 0 ) { $data{action} = $Q->param("action"); } my $fetch = ""; my $md5 = ""; my $server = "http://ru.download.ispsystem.com"; my $arch = ""; my $os = ""; my %md5Step = ( '/usr/bin/md5sum' => 0, '/sbin/md5' => 3 ); # Server IP address my $ip = $ENV{SERVER_ADDR}; if ( $CMD == 1 ) { if ( exists($data{ip}) ) { $ip = $data{ip}; } else { my $ifcfg = `ifconfig`; if ( $ifcfg =~ /inet.*?(\d+\.\d+\.\d+\.\d+)/s ) { $ip = $1; } } } my @vers = ( "BILLmanager", "BILLmanager-Corporate", "BILLmanager-Advanced", "BILLmanager-Standart", "BILLmanager-RUCENTER" ); my @avers = (); my %html = (); &getHtml(); &initVars(); &getLicList(); if ( $data{action} eq "install" ) { &install(); } &step1(); sub step1 { $data{version} = $Q->param("version"); $data{mhost} = $Q->param("mhost"); $data{mdb} = $Q->param("mdb"); $data{muser} = $Q->param("muser"); $data{mpass} = $Q->param("mpass"); $data{msock} = $Q->param("msock"); $data{ahttp} = $Q->param("ahttp"); $data{apass} = $Q->param("apass"); $data{apass2} = $Q->param("apass2"); # Set title my $content = $html{page}; $content =~ s/%TITLE%/&gm("page_title")/e; # Error handling if ( $errormsg ne "" ) { $errormsg = "
$errormsg
"; } $content =~ s/%ERROR%/$errormsg/; # Generate VERSIONS radio buttons my $vcontent = ""; my $n = 0; for ( @avers ) { my $checked = ( $data{version} eq $_ ) ? " checked" : ( $data{version} eq "" && $n == 0 ) ? " checked" : ""; $vcontent .= "$_"; $n++; } my $fcontent = $html{step1}; $fcontent =~ s/%VERSIONS%/$vcontent/; # MySQL vars if ( $data{mhost} eq "" ) { $data{mhost} = "localhost"; } $fcontent =~ s/%MHOST%/$data{mhost}/; $fcontent =~ s/%MDB%/$data{mdb}/; $fcontent =~ s/%MUSER%/$data{muser}/; $fcontent =~ s/%MPASS%/$data{mpass}/; $fcontent =~ s/%MSOCK%/$data{msock}/; # AHTTP my $ahttp = ( exists $data{ahttp} && $data{ahttp} eq "yes" ) ? " checked" : ""; $fcontent =~ s/%AHTTP%/$ahttp/; # Admin password $fcontent =~ s/%APASS%/$data{apass}/; $fcontent =~ s/%APASS2%/$data{apass2}/; # Insert form $content =~ s/%CONTENT%/$fcontent/; print "Content-Type: text/html\n\n"; #? for ( keys %ENV ) { print "$_ = $ENV{$_}
\n"; } print $content; exit 0; } sub install { if ( $CMD == 0 ) { $data{version} = $Q->param("version"); $data{mhost} = $Q->param("mhost"); $data{mdb} = $Q->param("mdb"); $data{muser} = $Q->param("muser"); $data{mpass} = $Q->param("mpass"); $data{msock} = $Q->param("msock"); $data{ahttp} = $Q->param("ahttp"); $data{apass} = $Q->param("apass"); $data{apass2} = $Q->param("apass2"); } # Check BILLmanager version if ( $CMD == 1 && !exists($data{version}) ) { $data{version} = "BILLmanager-RUCENTER"; } else { my $flag = 0; for ( @avers ) { if ( $_ eq $data{version} ) { $flag = 1; } } if ( $flag == 0 ) { &error("er_version"); } } # MySQL if ( $CMD == 1 && !exists($data{mhost}) ) { $data{mhost} = "localhost"; } if ( $data{mhost} !~ /^[\w\.\-]+$/ || length($data{mhost}) > 50 ) { &error("er_mhost"); } if ( $data{mdb} !~ /^[\w\.\-]+$/ || length($data{mdb}) > 50 ) { &error("er_mdb"); } if ( $data{muser} !~ /^[\w\.\-]+$/ || length($data{muser}) > 50 ) { &error("er_muser"); } if ( $data{mpass} eq "" || length($data{mpass}) > 50 ) { &error("er_mpass"); } if ( $data{msock} ne "") { if( !-e $data{msock}) {&error("er_msock");} } my $mpass = $data{mpass}; $mpass =~ s/([\(\)\'\&\;\|\$\"\\\<\>\?\*])/\\$1/g; my $sock_add = $data{msock} ne "" ? "--socket=$data{msock}" : ""; my $mstatus = `mysql -h $data{mhost} -u $data{muser} -p$mpass --execute=status $sock_add $data{mdb}`; if ( $mstatus eq "" ) { &error("er_mconnect"); } if ($data{mhost} eq "localhost" && $data{msock} eq "") { my $sock_var = `mysql --help | grep ^socket`; $sock_var =~ s/^\s+//; $sock_var =~ s/\s+$//; my ($fake, $path_to_sock) = split(/\s+/, $sock_var, 2); $data{msock} = $path_to_sock; }; # Set UTF-8 charset for database `mysql -h $data{mhost} -u $data{muser} -p$mpass $sock_add -e "ALTER DATABASE $data{mdb} DEFAULT CHARACTER SET utf8" $data{mdb}`; if ( $CMD == 1 ) { $data{ahttp} = "yes"; } if ( $CMD == 1 ) { if ( !exists($data{apass}) ) { $data{apass} = ""; my $chars = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; for ( my $i=0; $i<8; $i++ ) { $data{apass} .= substr($chars,int(rand(62)),1); } } $data{apass2} = $data{apass}; } if ( $data{apass} eq "" || length($data{apass}) > 100 ) { &error("er_apass"); } if ( $data{apass} ne $data{apass2} ) { &error("er_apassconfirm"); } my $cdir = `pwd`; chomp($cdir); if ( $CMD == 0 ) { $cdir = $ENV{DOCUMENT_ROOT}; } elsif ( exists $data{droot} ) { $cdir = $data{droot}; } # Download archive chdir($cdir); my $url = "$server/$os/$arch/$data{version}/install.tgz"; my $archive = "install.tgz"; if ( -e $archive ) { unlink $archive; unlink $archive.".md5"; } `$fetch $archive "$url"`; # Check md5 `$fetch $archive.md5 "$url.md5"`; $remotesum = `cat $archive.md5`; $localsum = `$md5 install.tgz`; my @remoteList = split(' ', $remotesum); my @localList = split(' ', $localsum); if ( $remoteList[$md5Step{$md5}] ne $localList[$md5Step{$md5}] ) { &error("er_md5sum"); } # UNPACK archive `tar xzpf $archive`; # Create Configure if ( !-e "etc/billmgr.conf" ) { `cp etc/dist/billmgr.conf etc/billmgr.conf`; } `chmod +ow etc/billmgr.conf`; open ( CNF, ">>etc/billmgr.conf" ) or &error("er_fopen","etc/billmgr.conf"); if ( $data{ahttp} eq "yes" ) { print CNF "Option AllowHTTP\n"; } print CNF "DBHost $data{mhost}\n"; print CNF "DBName $data{mdb}\n"; print CNF "DBUser $data{muser}\n"; print CNF "DBPassword $data{mpass}\n"; if ($data{msock} ne "") {print CNF "DBSocket $data{msock}\n";} close ( CNF ); # HTACCESS open ( AC, ">.htaccess") or &error("er_fopen",".htaccess"); print AC "Options +FollowSymLinks\n"; print AC "Order Deny,Allow\n"; print AC "Deny from all\n"; close ( AC ); open ( AC, ">cgi/.htaccess") or &error("er_fopen","cgi/.htaccess"); print AC "SetHandler cgi-script\n"; print AC "AddDefaultCharset utf-8\n"; print AC "Order Deny,Allow\n"; print AC "Allow from all\n"; print AC "Options -Indexes +ExecCGI\n"; print AC "SetEnv LD_LIBRARY_PATH $cdir/lib:$cdir/external/lib\n"; close ( AC ); open ( AC, ">skins/.htaccess") or &error("er_fopen","skins/.htaccess"); print AC "Order Deny,Allow\n"; print AC "Allow from all\n"; print AC "Options -Indexes\n"; close ( AC ); # Change notification E-mails my $billpath = "/cgi/billmgr"; if ( exists $ENV{DOCUMENT_ROOT} ) { $billpath = substr($cdir,length($ENV{DOCUMENT_ROOT}))."/cgi/billmgr"; } opendir ( DIR, "etc/dist/notify" ) or do { print "EKSEL MOKSEL"; }; for my $file ( readdir(DIR) ) { next if ( $file !~ /\.xsl/ ); my $content = ""; open ( F, "etc/dist/notify/$file" ); while ( ) { $content .= $_; } close ( F ); $content =~ s/https:/http:/gm if (exists $data{ahttp} && $data{ahttp} eq "yes" ); $content =~ s/\/manager\/billmgr/$billpath/gm; open ( F, ">etc/dist/notify/$file" ); print F $content; close ( F ); } closedir ( DIR ); # Links # `cp sbin/cgiclient cgi/billmgr`; `chmod 755 cgi/billmgr`; `chmod a-s cgi/*`; if ( $CMD == 0 ) { `ln -s $cdir/cgi $ENV{DOCUMENT_ROOT}/mancgi`; } else { my $lndir = ( exists $data{droot} ) ? $data{droot} : $cdir; `ln -s $cdir/cgi $lndir/mancgi`; } # License `$fetch etc/billmgr.lic -q "http://lic.ispsystem.com/billmgr.lic?ip=$ip"`; # Set admin password my $apass = $data{apass}; $apass =~ s/([\(\)\'\&\;\|\$\"\\\<\>\?\*])/\\$1/g; $ENV{LD_LIBRARY_PATH} = "$cdir/lib:$cdir/external/lib"; my $try_count = 0; my $auth_result = ""; while ($auth_result ne "OK" && $try_count lt 5) { `sbin/mgrctl -m billmgr usrparam passwd=$apass rows=50 recordlimit=1000 sok=yes`; $auth_result = `sbin/mgrctl -m billmgr usrparam authinfo=admin:$apass rows=50 recordlimit=1000 sok=yes`; $auth_result =~ s/^\s+//; $auth_result =~ s/\s+$//; $try_count++; } if ($auth_result ne "OK") { open (CNF, ") { chomp $line; if (!($line =~ m/DBHost/) && !($line =~ m/DBName/) && !($line =~ m/DBUser/) && !($line =~ m/DBPassword/) && !($line =~ m/DBSocket/)) { push @billparam, $line; } } open ( CNF, ">etc/billmgr.conf" ) or &error("er_fopen","etc/billmgr.conf"); for my $conf_line( @billparam ) { print CNF "$conf_line\n"; } close ( CNF ); open ( AC, ">.htaccess") or &error("er_fopen",".htaccess"); print AC "Options +FollowSymLinks\n"; print AC "Order Allow,Deny\n"; print AC "Allow from all\n"; close ( AC ); &error("er_setpasswd", $auth_result); } # Redirect to billing if ( $CMD == 0 ) { my $burl; if ( $data{ahttp} ne "yes" ) { $burl = "https://"; } else {$burl = "http://"; } $burl .= $ENV{HTTP_HOST}; $burl .= "/cgi/billmgr?username=admin"; print "Location: $burl\n\n"; # Or write admin password } else { print "OK\nadmin password : $data{apass}\n"; } exit 0; } # Get available licenses sub getLicList { my $liclist = `$fetch - -q "http://lic.ispsystem.com/liclist.cgi?ip=$ip"`; my @tvers = (); for my $av ( split( /\n/, $liclist ) ) { if ( $av =~ /BILLmanager/ ) { my $flag = 0; for my $v ( @vers ) { if ( $av eq $v ) { $flag = 1; } if ( $flag == 1 ) { $tvers{$v} = 1; } } } } delete( $tvers{BILLmanager} ); for ( @vers ) { if ( exists( $tvers{$_} ) ) { push( @avers, $_ ); } } if ( $#avers == -1 ) { &error("er_lic",$ip); } } # Initialize variables sub initVars { # fetch command if ( -x "/usr/bin/fetch" ) { $fetch = "/usr/bin/fetch -q -o "; } elsif ( -x "/usr/bin/wget" ) { $fetch = "/usr/bin/wget -O "; } elsif ( -x "/usr/bin/curl" ) { $fetch = "/usr/bin/curl -o "; } else { &error("er_fetch"); } # md5 command if ( -x "/sbin/md5" ) { $md5 = "/sbin/md5"; } elsif ( -x "/usr/bin/md5sum" ) { $md5 = "/usr/bin/md5sum"; } else { &error("er_md5"); } # arch $arch = `uname -m`; chomp($arch); if ( $arch eq "" ) { &error("er_arch"); }; # os my $kern = `uname -s`; chomp($kern); if ( exists $data{os} ) { $os = $data{os}; } elsif ( $kern eq "FreeBSD" ) { my $ver = `uname -r`; if ( $ver =~ /^(\d+\.\d+)/ ) { $os = "$kern-$1"; } else { &error("er_os"); } } elsif ( $kern eq "Linux" ) { $os = "Linux-cc6"; } else { &error("er_os"); } # check mysql binary my $mysqlv = `mysql --version`; if ( $mysqlv eq "" ) { &error("er_mysql"); } # check tar binary my $tarv = `tar --version`; if ( $tarv eq "" ) { &error("er_tar"); } } sub printCmdHelp { print "Usage: install.cgi OPTIONS\n"; print " --path=absolute_path [Optional] [Default: current directory] Installation directory\n"; print " --droot=absolute_path [Optional] [Default: same as --path] Site DOCUMENT_ROOT directory\n"; print " --ip=x.x.x.x [Optional] [Default: first server IP-address] License IP-address\n"; print " --version=BILLmanager_version [Optional] [Default: BILLmanager-RUCENTER] BILLmanager version\n"; print " --mhost=host [Optional] [Default: localhost] MySQL host\n"; print " --mdb=database [Mandatory] MySQL database\n"; print " --muser=user [Mandatory] MySQL user\n"; print " --mpass=password [Mandatory] MySQL user password\n"; print " --msock=mysql_sock_path [Optional] MySQL sock path\n"; print " --apass=password [Optional] BILLmanager admin user password\n"; print " --os=OS [Optional] Server Operating System\n"; exit 1; } # Get messages in user language sub gm { my ( $name, @params ) = @_; my $m = $msg{$lang}{$name}; if ( $m eq "" ) { $m = $msg{en}{$name}; } if ( $#params != -1 ) { $m = sprintf($m,@params); } return $m; } # Error handling sub error { my ( @params ) = @_; $errormsg = &gm(@params); if ( $CMD == 1 ) { print $errormsg."\n\n"; &printCmdHelp(); } if ( $Q->param("action") eq "install" ) { &step1(); } my $content = $html{page}; my $ftitle = &gm("page_title"); $content =~ s/%TITLE%/$ftitle/; $content =~ s/%CONTENT%/
$errormsg<\/div>/; print "Content-Type: text/html\n\n"; print $content; exit 0; } sub getHtml { $html{page} = < %MSG_page_title%
%TITLE%
%ERROR% %CONTENT%
PAGE $html{step1} = <%MSG_installdesc%
         
%VERSIONS%
%MSG_versiondesc%
%MSG_mysqldesc%
%MSG_mysqlhost%
%MSG_mysqldb%
%MSG_mysqluser%
%MSG_mysqlpass%
%MSG_mysqlsock%
%MSG_ahttpdesc%
%MSG_ahttp%
%MSG_apassdesc%
%MSG_apass%
%MSG_apass2%
STEP1 # Replace messages for $key ( keys %html ) { $html{$key} =~ s/%MSG_([^%]+)%/&gm($1)/ge; } }