#VERSION,2.06
###############################################################################
#  Copyright (C) 2007 Chris Sullo
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; version 2
#  of the License only.
#
#  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 General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to
#  Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
###############################################################################
# PURPOSE:
# HTML Reporting
###############################################################################
sub nikto_report_html_init {
    my $id = { name              => "report_html",
               full_name         => "Report as HTML",
               author            => "Sullo/Jabra",
               description       => "Produces an HTML report.",
               report_head       => \&html_head,
               report_summary    => \&html_summary,
               report_host_start => \&html_host_start,
               report_host_end   => \&html_host_end,
               report_item       => \&html_item,
               report_close      => \&html_close,
               report_format     => 'htm',
               copyright         => "2008 Chris Sullo"
               };

    # load up the templates now
    html_open_templates();
    return $id;
}
###############################################################################
sub html_head {
    my ($file) = @_;
    print STDERR "+ ERROR: Output file not specified.\n" if $file eq '';

    # Write header for html file, return file handle
    open(OUT, ">>$file") || die print STDERR "+ ERROR: Unable to open '$file' for write: $@\n";

    my $html = html_change_vars($TEMPLATES{'htm_start'});
    $html =~ s/\#NIKTODTD#/$CONFIGFILE{'NIKTODTD'}/;
    print OUT "$html";

    return OUT;
}
###############################################################################
sub html_close {
    my ($handle, $mark) = @_;
    my $html = html_change_vars($TEMPLATES{'htm_close'}, $mark);
    print $handle "$html\n";

    close($handle);
    return;
}
###############################################################################
sub html_summary {
    my ($handle, $mark) = @_;
    my $html = html_change_vars($TEMPLATES{'htm_summary'}, $mark);
    print $handle $html;

    return;
}
###############################################################################
sub html_host_start {
    my ($handle, $mark) = @_;
    my $html = html_change_vars($TEMPLATES{'htm_host_head'}, $mark);
    print $handle "$html\n";

    return;
}
###############################################################################
sub html_host_end {
    my ($handle, $mark) = @_;
    my $html = html_change_vars($TEMPLATES{'htm_end'}, $mark);
    print $handle "$html\n";

    return;
}
###############################################################################
sub html_item {
    my ($handle, $mark, $item) = @_;
    my $html = html_change_vars($TEMPLATES{'htm_host_item'}, $mark, $item);
    print $handle "$html\n";

    return;
}
###############################################################################
sub html_open_templates {
    foreach my $t (dirlist($CONFIGFILE{'TEMPLATEDIR'}, "htm.*")) {
        open(T, "<$CONFIGFILE{'TEMPLATEDIR'}/$t");
        my @TEMPLATE = <T>;
        close(T);
        my $T = join("", @TEMPLATE);
        $t =~ s/\..*$//;
        $TEMPLATES{$t} = $T;
    }

    return;
}
###############################################################################
sub html_change_vars {
    my ($template, $mark, $item) = @_;
    my %variables;
    my $protocol = "http";
    if ($mark->{'ssl'}) { $protocol .= "s"; }
    my $hostname = $mark->{'vhost'} ? $mark->{'vhost'} : $mark->{'hostname'};

    $variables{"#TEMPL_HCTR#"}        = $VARIABLES{'TEMPL_HCTR'};
    $variables{"#TEMPL_END#"}         = date_disp($mark->{'end_time'});
    $variables{"#TEMPL_HOSTNAME#"}    = simple_enc($hostname);
    $variables{"#TEMPL_IP#"}                 = simple_enc($mark->{'ip'});
    $variables{"#TEMPL_ITEMS_TESTED#"}       = $COUNTERS{'total_checks'};
    $variables{"#TEMPL_PORT#"}               = $mark->{'port'};
    $variables{"#TEMPL_NIKTO_VER#"}          = $VARIABLES{'version'};
    $variables{"#TEMPL_BANNER#"}             = simple_enc($mark->{'banner'});
    $variables{"#TEMPL_NIKTO_CLI#"}          = $CLI{'all_options'};
    $variables{"#TEMPL_CTR#"}                = $COUNTERS{'total_checks'};
    $variables{"#TEMPL_NIKTO_HOSTS_TESTED#"} = $COUNTERS{'hosts_completed'};
    $variables{"#TEMPL_LINK_IP#"} =
      $protocol . "://" . $mark->{'ip'} . ":" . $mark->{'port'} . $mark->{'root'};
    if ($variables{"#TEMPL_LINK_IP#"} !~ /\/$/) { $variables{"#TEMPL_LINK_IP#"} .= '/'; }
    $variables{"#TEMPL_ITEMS_FOUND#"}  = $mark->{'total_vulns'};
    $variables{"#TEMPL_SCAN_START#"}   = localtime($COUNTERS{'scan_start'});
    $variables{"#TEMPL_SCAN_END#"}     = localtime($COUNTERS{'scan_end'});
    $variables{"#TEMPL_SCAN_ELAPSED#"} = $COUNTERS{'scan_elapsed'} . " seconds";
    $variables{"#TEMPL_STATISTICS#"} =
      "$COUNTERS{'totalrequests'} requests, $mark->{'total_errors'} errors, $mark->{'total_vulns'} findings";
    $variables{"#TEMPL_START#"}   = date_disp($mark->{'start_time'});
    $variables{"#TEMPL_ELAPSED#"} = $mark->{'end_time'} - $mark->{'start_time'};

    $variables{"#TEMPL_LINK_NAME#"} = "N/A";
    if ($hostname ne "") {
        $variables{"#TEMPL_LINK_NAME#"} =
          $protocol . "://" . $hostname . ":" . $mark->{'port'} . $mark->{'root'};
    }
    if ($variables{"#TEMPL_LINK_NAME#"} !~ /\/$/) { $variables{"#TEMPL_LINK_NAME#"} .= '/'; }

    $variables{"#ID#"} = $item->{'nikto_id'};

    # OSVDB info
    my $OSVDB = $item->{'osvdb'};
    if ($OSVDB !~ /\d+/) { $OSVDB = 0; }
    $variables{"#TEMPL_OSVDB_LINK#"} = "http://osvdb.org/$OSVDB";
    $variables{"#TEMPL_OSVDB#"}      = $OSVDB;

    # Scanner Messages Handling
    $variables{"#TEMPL_SMMSG#"} = $item->{'message'};

    # Positives Handling
    if ($template =~ /\#TEMPL_MSG#/) {
        my $msg = simple_enc($item->{'message'});

        # Message & handling for customized html output
        # 740000 = multiple index files -- linkify file names
        if ($item->{'nikto_id'} == 740000) {
            $item->{'message'} =~ /^(.*: )(.*)$/;
            $msg = $1;
            my @links;
            foreach my $f (parse_csv($2)) {    #@files) {
                $f =~ s/\s//g;
                next if $f eq '';
                push(@links,
                     "<a href=\"$protocol://$mark->{'display_name'}:$mark->{'port'}/$f\">$f</a>");
            }
            $msg .= join(", ", @links);
        }

  	my $uri = $item->{'uri'};
        if (($uri ne '') && ($uri !~ /^$mark->{'root'}/))
		{ $uri = $mark->{'root'} . $uri; }
        $variables{"#TEMPL_URI#"}         = simple_enc($uri);
        $variables{"#TEMPL_MSG#"}         = $msg;
        $variables{"#TEMPL_HTTP_METHOD#"} = simple_enc($item->{'method'});
        $variables{"#TEMPL_ITEM_IP_LINK#"} =
          "$protocol://$variables{\"#TEMPL_IP#\"}:$mark->{'port'}$variables{\"#TEMPL_URI#\"}";
        $variables{"#TEMPL_ITEM_NAME_LINK#"} = "";
        if ($hostname ne "") {
            $variables{"#TEMPL_ITEM_NAME_LINK#"} = "$protocol://$hostname:$mark->{'port'}$variables{\"#TEMPL_URI#\"}";
        }
    }

    foreach my $var (keys %variables) {
        $template =~ s/$var/$variables{$var}/g;
    }

    return $template;
}
###############################################################################
sub simple_enc {
    my $var = $_[0] || return;
    $var =~ s/</&lt;/g;
    $var =~ s/>/&gt;/g;
    $var =~ s/"/&quot;/g;
    return $var;
}

1;
