package MySQL::Admin::GUI;
use strict;
use warnings;
use utf8;
use DBI::Library::Database qw(:all);
use HTML::Menu::Pages;
use MySQL::Admin qw(:all :lze :cgi-lib);
use HTML::Entities;
use User::pwent;
use MySQL::Admin::Settings;
use MySQL::Admin::Translate;
use MySQL::Admin::Config;
use MySQL::Admin::Session;
use Encode;
use Fcntl qw(:flock);
use Symbol;
use URI::Escape;

# use CGI::Carp qw(fatalsToBrowser);
require Exporter;
use vars qw(
  $DefaultClass
  $ACCEPT_LANGUAGE
  @EXPORT
  @ISA
  @m_aCookies
  $m_bMod_perl
  %m_hUniq
  $m_hrAct
  $m_hrParams
  $m_hrSettings
  $m_hrLng
  $m_nStart
  $m_nEnd
  $m_nRight
  $m_nSize
  $m_oDatabase
  $m_dbh
  $m_sAction
  $m_sFile
  $m_sSid
  $m_sStyle
  $m_sSub
  $m_sTitle
  $m_sUser
  $m_sContent
  $m_hContent
  $m_sCurrentDb
  $m_sCurrentHost
  $m_sCurrentUser
  $m_sCurrentPass
  $m_sAjax
  $m_nSkipCaptch
);
@MySQL::Admin::GUI::EXPORT  = qw(ContentHeader Body ChangeDb Unique);
@ISA                        = qw(Exporter MySQL::Admin);
$MySQL::Admin::GUI::VERSION = '0.73';
$m_bMod_perl                = ( $ENV{MOD_PERL} ) ? 1 : 0;
local $^W = 0;
$m_sAjax = qq(<?xml version="1.0" encoding="UTF-8"?>\n<xml>);
$m_nSkipCaptch = 0;
=head1 NAME

MySQL::Admin::GUI - Just a MySQL administration Web-App

=head1 SYNOPSIS

        use MySQL::Admin::GUI;
        ContentHeader("config/settings.pl");
        print Body();


=head2 EXPORT

        action Body maxlength openFile

=cut

=head2 ContentHeader()

     ContentHeader("/path/to/your/settings.pl");

=cut

sub ContentHeader {
    my $m_hrSettingsfile = shift;
    init($m_hrSettingsfile);
    $m_oDatabase = new DBI::Library::Database();
    $m_oDatabase->rewrite( $m_hrSettings->{cgi}{mod_rewrite} );
    $m_oDatabase->serverName( $m_hrSettings->{cgi}{serverName} );
    $m_oDatabase->floodtime( $m_hrSettings->{floodtime} );
    $m_dbh = $m_oDatabase->initDB(
        {
            name     => $m_hrSettings->{database}{name},
            host     => $m_hrSettings->{database}{host},
            user     => $m_hrSettings->{database}{user},
            password => $m_hrSettings->{database}{password},
        }
    );
    $m_sCurrentDb =
        param('m_ChangeCurrentDb')
      ? param('m_ChangeCurrentDb')
      : $m_hrSettings->{database}{CurrentDb};
    $m_sAction =
      param('action') ? param('action') : $m_hrSettings->{defaultAction};

    $m_sAction =
      ( $m_sAction =~ /^(\w{3,50})$/ )
      ? $1
      : $m_hrSettings->{defaultAction};
    $m_sCurrentHost =
        param('m_shost')
      ? param('m_shost')
      : $m_hrSettings->{database}{CurrentHost};
    $m_sCurrentUser =
        param('m_suser')
      ? param('m_suser')
      : $m_hrSettings->{database}{CurrentUser};
    $m_sCurrentPass =
        param('m_spass')
      ? param('m_spass')
      : $m_hrSettings->{database}{CurrentPass};

    if ( param('m_ChangeCurrentDb') ) {
        $m_hrSettings->{database}{CurrentDb}   = $m_sCurrentDb;
        $m_hrSettings->{database}{CurrentHost} = $m_sCurrentHost;
        $m_hrSettings->{database}{CurrentUser} = $m_sCurrentUser;
        $m_hrSettings->{database}{CurrentPass} = $m_sCurrentPass;
        $m_sAction                             = 'ShowTables';
        saveSettings($m_hrSettingsfile);
    }
    my $cookiepath = $m_hrSettings->{cgi}{cookiePath};

    $m_sSid = cookie( -name => 'sid' ) ? cookie( -name => 'sid' ) : '123';

  $m_sUser =
      defined $m_oDatabase->getName($m_sSid)
      ? $m_oDatabase->getName($m_sSid)
      : 'guest';
    if ( $m_sAction eq 'logout' or  ($m_sAction ne 'login' and $m_sUser eq 'guest') ) {
        my $cookie = cookie(
            -name    => 'sid',
            -value   => '',
            -expires => '-1d',
            -path    => "$cookiepath"
        );
        $m_sAjax .=
            '<output id="login"><![CDATA['
          . do('$m_hrSettings->{cgi}{bin}/Sidebar/exploit.pl')
          . ']]></output>';
        push @m_aCookies, $cookie;
        print header(
            -type    => 'text/xml',
            -charset => 'UTF-8',
            -cookie  => [@m_aCookies]
        );
        $m_sUser   = 'guest';
        $m_sSid    = '123';
        $m_sAction = 'showLogin';
    }
    elsif ( $m_sAction eq 'login' ) {
        my $ip = remote_addr();
        my $u  = param('user');
        my $p  = param('pass');
        $m_nSkipCaptch = 0;
        eval('
	use Authen::Captcha;
        my $captcha = Authen::Captcha->new(data_folder   => "$m_hrSettings->{cgi}{bin}/config/",
                                           output_folder => "$m_hrSettings->{cgi}{DocumentRoot}/images");
        $m_nSkipCaptch = $captcha->check_code(param("captcha"), param("md5"));
        ');
        $m_nSkipCaptch = 1 if $@; # skip captcha without gd
        if ( defined $u && defined $p && defined $ip && $m_nSkipCaptch > 0) {
            use MD5;
            my $md5 = new MD5;
            $md5->add($u);
            $md5->add($p);
            my $cyrptpass = $md5->hexdigest();
            my $result    = 1;
            if ( $m_oDatabase->checkPass( $u, $cyrptpass ) ) {

                $m_sSid = $m_oDatabase->setSid( $u, $p, $ip );
                my $cookie = cookie(
                    -name    => 'sid',
                    -value   => "$m_sSid",
                    -path    => "$cookiepath",
                    -expires => '+1y'
                );
                push @m_aCookies, $cookie if $result eq 1;
                print header(
                    -type    => 'text/xml',
                    -charset => 'UTF-8',
                    -cookie  => [@m_aCookies]
                );

            }
            else {
                print header(
                    -type    => 'text/xml',
                    -charset => 'UTF-8',
                    -cookie  => [@m_aCookies]
                );
            }
        }
        else {
            print header(
                -type    => 'text/xml',
                -charset => 'UTF-8',
                -cookie  => [@m_aCookies]
            );
        }
        $m_sAction = 'ShowDatabases';
    }
    else {
        print header(
            -type    => 'text/xml',
            -charset => 'UTF-8',
            -cookie  => [@m_aCookies]
        );
    }
}

=head2 Body()

     print Body();

=cut

sub Body {
    $m_sStyle = $m_hrSettings->{cgi}{style};
    $m_sUser =
      defined $m_oDatabase->getName($m_sSid)
      ? $m_oDatabase->getName($m_sSid)
      : 'guest';
    $m_nStart = param('von')               ? param('von') : 0;
    $m_nStart = ( $m_nStart =~ /^(\d+)$/ ) ? $1           : 0;
    $m_nEnd   = param('bis')               ? param('bis') : 10;
    $m_nEnd   = ( $m_nEnd =~ /^(\d+)$/ )   ? $1           : 0;
    if ( $m_nStart < 0 ) {
        $m_sAction = 'exploit';
        $m_nStart  = 0;
    }

    $m_hrAct = $m_oDatabase->getAction($m_sAction);

    $m_hrAct =
      defined $m_hrAct
      ? $m_hrAct
      : $m_oDatabase->getAction( $m_hrSettings->{'defaultAction'} );
    $m_sTitle = $m_hrAct->{title};
    $m_sFile  = $m_hrAct->{file};
    $m_sSub   = $m_hrAct->{sub};
    $m_nRight =
        $m_oDatabase->userright($m_sUser)
      ? $m_oDatabase->userright($m_sUser)
      : 0;


    if ( defined $m_hrAct->{box} ) {

        my @boxes = split / /, $m_hrAct->{box};
        foreach my $box (@boxes) {
            $m_sContent = "";
            my $bx = $m_oDatabase->fetch_hashref(
                "select * from box where `file` = ? && `right` <= ? ",
                "$box.pl", $m_nRight );
            do("$m_hrSettings->{cgi}{bin}/Sidebar/$bx->{file}")
              if ( defined $bx->{file}
                && -e "$m_hrSettings->{cgi}{bin}/Sidebar/$bx->{file}" );
            $m_sAjax .= "<output id=\"errorMessage\"><![CDATA[$@]]></output>"
              if ($@);
            $m_sAjax .=
                "<output id=\"$bx->{outId}\"><![CDATA["
              . $m_sContent
              . ']]></output>'
              if $m_sContent;
            $m_sContent = "";
        }
    }
    if(param('include')){
      include(param('include'));
    }else{
      do("$m_hrSettings->{cgi}{bin}/Sidebar/exploit.pl");
    }
    $m_sAjax .= '<output id="login"><![CDATA[' . $m_sContent . ']]></output>';
    $m_sContent = '';

    if ( $m_nRight >= $m_hrAct->{right} ) {
        if ( defined $m_sFile and defined $m_sSub ) {
            $m_sContent = "";
            do("$m_hrSettings->{cgi}{bin}/Content/$m_sFile");
            eval($m_sSub) if $m_sSub ne 'main';
            if ($@) {
                $m_sAjax .=
                  '<output id="content"><![CDATA[' . $@ . ']]></output>';
            }
            else {
                $m_sAjax .=
                    '<output id="content"><![CDATA['
                  . $m_sContent
                  . ']]></output>';
            }
            $m_dbh = $m_oDatabase->initDB(
                {
                    name     => $m_hrSettings->{database}{name},
                    host     => $m_hrSettings->{database}{host},
                    user     => $m_hrSettings->{database}{user},
                    password => $m_hrSettings->{database}{password},
                }
            );

        }
        else {
            $m_sContent = "";
            do("$m_hrSettings->{cgi}{bin}/Content/exploit.pl");

            #eval($m_sSub) if $m_sSub ne 'main';
            if ($@) {
                $m_sAjax .=
                  '<output id="content"><![CDATA[' . $@ . ']]></output>';
            }
            else {
                $m_sAjax .=
                    '<output id="content"><![CDATA['
                  . $m_sContent
                  . ']]></output>';
            }
        }
    }
    else {
        $m_sContent = "";
        do("$m_hrSettings->{cgi}{bin}/Content/exploit.pl");
        if ($@) {
            $m_sAjax .= '<output id="content"><![CDATA[' . $@ . ']]></output>';
        }
        else {
            $m_sAjax .=
              '<output id="content"><![CDATA[' . $m_sContent . ']]></output>';
        }
    }

    $m_sContent .= '</tr></table>';
    clearSession();
    return $m_sAjax . "</xml>";
}

=head2 ChangeDb

        my %db = {

                name => '',

                host   => '',

                user => '',

                password => '',

       };

       ChangeDb(\%db);

=cut

sub ChangeDb {
    my $hash = shift;
    my $m_sTitle = $hash->{title} if ( defined $hash->{title} );
    $m_dbh = $m_oDatabase->initDB(
        {
            name     => $hash->{name},
            host     => $hash->{host},
            user     => $hash->{user},
            password => $hash->{password},
        }
    );
}

=head2 Unique()

        $unique =Unique();

=cut

sub Unique {
    my $unic;
    do { $unic = int( rand(1000000) ); } while ( defined $m_hUniq{$unic} );
    $m_hUniq{$unic} = 1;
    return $unic;
}

=head1 SEE ALSO

L<CGI> L<MySQL::Admin>
L<DBI> L<DBI::Library> L<DBI::Library::Database>
L<MySQL::Admin::Main> L<HTML::TabWidget>  L<HTML::Menu::Pages>


=head1 AUTHOR

Dirk Lindner <dirk.lze@gmail.com>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2005-2015 by Hr. Dirk Lindner

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation;
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

=cut

1;
