/* Nessus
 * Copyright (C) 1998 - 2001 Renaud Deraison
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2,
 * 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 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 the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * 
 * In addition, as a special exception, Renaud Deraison
 * gives permission to link the code of this program with any
 * version of the OpenSSL library which is distributed under a
 * license identical to that listed in the included COPYING.OpenSSL
 * file, and distribute linked combinations including the two.
 * You must obey the GNU General Public License in all respects
 * for all of the code used other than OpenSSL.  If you modify
 * this file, you may extend this exception to your version of the
 * file, but you are not obligated to do so.  If you do not wish to
 * do so, delete this exception statement from your version.
 * 
 * Output modified by Isaac Dawson of Security Management Partners. 
 *
 * changes to generate valid html: Axel Nennker axel@nennker.de
 * 20020919 see: http://validator.w3.org/file-upload.html
 *  - an attribute vaule must be quoted if it contains any character
 *    other than letters(A-Za-z), digits, hyphens and periods
 *  - added charset iso-8859-1
 * 20020924 Axel Nennker axel@nennker.de
 *  some more fixes for valid html4.0
 *
 */

/** @file
 * Export of report to html.
 */

#include <includes.h>
#include "report.h"
#include "report_utils.h"
#include "error_dlg.h"
#include "preferences.h"
#include "backend.h"
#include "html_output.h"

/* Created from backend_convert, when a severity_filter is active, gives the
   mapping matrix. */
extern int sev_mapping_matrix[6][6];

static void summary_to_file(FILE *, struct arglist *, gboolean, gboolean);

/*
 * Handy functions
 */

/**
 * @brief print URL linking to CVE/BID/OpenVAS database to file.
 *
 * '%s' in urlfmt (from preferences) will be replaced by
 * item IDs (or their parts split at minus characters).
 * '%%' will insert a percent character.
 * Everything else after '%' aborts parsing.
 * If urlfmt yields an empty string (e.g. it is only "%"),
 * only the item ID will be printed.
 */
void
html_output_fprint_link (FILE* file, const char* key, const char*  item)
{
  char *itemparts = estrdup(item);
  char *itemsrc = itemparts;
  char *urlfmt = estrdup(prefs_get_string(Global, key));
  char *src = urlfmt;
  char *url = emalloc(strlen(urlfmt)+strlen(item)+1);
  char *dst = url;
  char *tmp;

  while((tmp = strchr(src, '%')))
  {
    *tmp = '\0';
    strcpy(dst, src);
    dst += strlen(src);
    src = tmp+1;
    switch(*src)
    {
      case 's':
	if((tmp = strchr(itemsrc, '-')))
	  *tmp = '\0';
	strcpy(dst, itemsrc);
	dst += strlen(itemsrc);
	if(tmp)
	  itemsrc = tmp+1;
	src++;
	break;
      case '%':
	strcpy(dst++, "%");
	src++;
	break;
      default:
	*src = '\0';
    }
  }
  strcpy(dst, src);

  efree(&itemparts);
  efree(&urlfmt);
  if(*url)
    fprintf(file, "<a href=\"%s\">%s</a>", url, item);
    // In pdf_output was: strcmp("url_nessus", key) ? "" : "1.3.6.1.4.1.25623.1.0.", item);
  else
    fprintf(file, "%s", item);
  efree(&url);
}

/**
 * @brief All the cross references (CVE, BID) have the same format -
 * @brief XREF: \<num\>,...\<br\>
 * 
 * @file File to write to.
 */
char*
html_output_extract_xref (FILE* file, char* str, char* key)
{
 while(str != NULL && strncmp(str, "<br>", 4) != 0)
   {
    char * e1 = strchr(str, ',');
    char * e2 = strchr(str, '<');
    char tmp = '\0';
    if ((e1 > e2) || (e1 == NULL)) e1 = e2;

    if (e1 != NULL)
      {
        tmp = e1[0];
        e1[0] = '\0';
      }
    html_output_fprint_link(file, key, str);
    str = e1;
    if (e1 != NULL)
      {
        e1[0] = tmp;

        if (tmp == ',')
          {
            fputc (',', file);
            fputc (' ', file);
            str ++;
            str ++;
          }
        else
          fputc ('<', file);
      }
   }
  return str;
}

void
html_output_print_data_with_links (FILE* file, char* str, char* plugin_oid,
                                   gboolean internal_link)
{
 while(str != NULL && str[0] != '\0')
 {
  if(strncmp(str, "http:", 5) == 0 || strncmp(str, "https:", 6) == 0 )
  {
   char * e1, * e2;
   char tmp = 0;

   e1 = strchr(str, ' ');
   e2 = strstr(str, "<br>");
   if((e1 > e2) || (e1 == NULL))e1 = e2;

   if(e1 != NULL)
   {
    tmp = e1[0];
    e1[0] = '\0';
   }
   fprintf(file, "<a href=\"%s\">%s</a>", str, str);
   str += strlen(str) - 1;
   if(e1 != NULL)
   {
    e1[0] = tmp;
   }
  }
  else if(strncmp(str, "CVE : ", 6) == 0)
  {
   fprintf(file, "CVE : ");
   str += 6;
   str = html_output_extract_xref(file, str, "url_cve");
  }
  else if(strncmp(str, "BID : ", 6) == 0)
  {
  fprintf(file, "BID : ");
  str += 6;
  str = html_output_extract_xref(file, str, "url_bid");
  }
  else fputc(str[0], file);
  if(str != NULL)
    str++;
 }

 fprintf(file, "OID : ");
 if (internal_link == TRUE)
   fprintf(file, "<a href=\"#nvt%s\">%s</a>", plugin_oid, plugin_oid);
 else
   html_output_fprint_link(file, "url_nessus", plugin_oid);
}

/**
 * @brief Replaces newlines and \<, \> by "\<br\>" and "\&gt;"" , "\&lt;".
 * 
 * @param str String to convert.
 * @return String str where newlines and \<, \> have been replaced by html tags.
 */
char*
html_output_convert_cr_to_html (char* str)
{
  int num = 0;
  char * t;
  char * ret;
  int i, j = 0;

  /* Compute the size we'll need  */
  t = str;
  while (t[0])
    {
      if((t[0]=='\n')||(t[0]=='>')||(t[0]=='<'))
        num++;
      t++;
    }

  ret = emalloc (strlen(str)+5*num+1);
  for (i=0, j=0;str[i];i++,j++)
  {
   if(str[i]=='\n'){
   	ret[j++]='<';
	ret[j++]='b';
	ret[j++]='r';
	ret[j++]='>';
	ret[j]='\n';
	}
   else if(str[i]=='>') {
    	ret[j++]='&';
	ret[j++]='g';
	ret[j++]='t';
	ret[j]=';';
	}
  else if(str[i]=='<')
  	{
	ret[j++]='&';
	ret[j++]='l';
	ret[j++]='t';
	ret[j]=';';
	}
  else ret[j] = str[i];
  }
  return ret;
}


char*
html_output_portname_to_ahref (char* name, char* hostname)
{
  char *t, *k;

  hostname = t = estrdup (hostname);
  /* Convert '192.168.1.1' to '192_168_1_1' or
   * 'prof.nessus.org' to'prof_nessus_org' */
  while ((t = strchr (t, '.')) != 0)
    t [0] = '_';
  if (name == 0)
    return hostname;

  /* Convert 'telnet (21/tcp)' to '21_tcp' */
  name =
    k = estrdup (name);
  if ((t = strrchr (k, '(')) != 0) 
    k = t + 1;
  if ((t = strchr (k, ')')) != 0)
    t [0] = '\0' ;
  while ((t = strchr (k, '/')) != 0)
    t [0] = '_' ;

  /* append: "name" + "_" + "hostname" */
  t = emalloc (strlen (hostname) + strlen (k) + 2);
  strcat (strcat (strcpy (t, hostname), "_"), k);
  efree (&hostname);
  efree (&name);
  return t;
}


/**
 * @brief Prints the contents of the "ports" table, with links into the table
 * @brief with more details.
 * 
 * @param file         File to write to.
 * @param open         "Ports" arglist.
 * @param hostname     Name of the current host.
 * @param drop_fp      Whether or not to drop (TRUE) issues that have been
 *                     defined as False Positives.
 * @param drop_no_info Whether or not to drop open ports for which no message
 *                     (or only LOG and DEBUG) has ben sent.
 */
static void
html_output_print_port_table (FILE* file, struct arglist * open, char* hostname,
                              gboolean drop_fp, gboolean drop_no_info)
{
  char* name = NULL;

  while (open && open->next)
    {
      name = html_output_portname_to_ahref (open->name, hostname);
      if (name)
        {
          if (arg_get_value (open->value, "REPORT") ||
              arg_get_value (open->value, "INFO") ||
              arg_get_value (open->value, "FALSE") ||
              arg_get_value (open->value, "NOTE"))
            {
              // If there is just a False Positive registered for this port
              // and the user does not want to see False Positives, do not
              // list this port
              if (   drop_fp == TRUE
                  && arg_get_value (open->value, "FALSE")
                  && !(  arg_get_value (open->value, "REPORT")
                      || arg_get_value (open->value, "INFO")
                      || arg_get_value (open->value, "NOTE")
                      ))
                {
                  efree (&name);
                  open = open->next;
                  continue;
                }

              fprintf (file, "   <tr>\n\t<td class=default width=\"20%%\">%s</td>\n", hostname);
              fprintf (file, "\t<td class=default width=\"30%%\"><a href=\"#%s\">%s</a></td>\n", name, open->name);
              if (arg_get_value (open->value, "REPORT"))
                fprintf (file, "\t<td class=default width=\"30%%\"><font color=red>Security hole(s) </font></td></tr>\n");
              else if (arg_get_value (open->value, "INFO"))
                fprintf (file, "\t<td class=default width=\"30%%\">Security warning(s) </td></tr>\n");
              else if (arg_get_value (open->value, "NOTE"))
                fprintf (file, "\t<td class=default width=\"30%%\">Security note(s) </td></tr>\n");
              else if (arg_get_value (open->value, "FALSE"))
                fprintf (file, "\t<td class=default width=\"30%%\">False positive(s) </td></tr>\n");
              else
                fprintf (file, "\t<td class=default width=\"30%%\">Unknown issue(s)</td></tr>\n");
            }
          else if (drop_no_info == FALSE)
            {
              fprintf (file, "   <tr>\n\t<td class=default width=\"20%%\">%s</td>\n", hostname);
              fprintf (file, "\t<td class=default width=\"30%%\">%s</td>\n\t<td class=default width=\"30%%\">No Information</td></tr>\n", open->name);
            }
          efree (&name);
        }
      else if (drop_no_info == FALSE)
        {
          fprintf (file, "   <tr>\n\t<td class=default width=\"20%%\">%s</td>\n", hostname);
          fprintf (file, "\t<td class=default width=\"30%%\">%s</td>\n\t<td class=default width=\"30%%\">No Information</td></tr>\n", open->name);
        }
      open = open->next;
    }
  fprintf (file, "</tbody></table></td></tr></tbody></table><br><br>\n");
}

/**
 * @brief In the 'Security Issues and Fixes' table for a single host,
 * @brief print rows describing issues of a certain type (e.g.
 * @brief "security warnings").
 * 
 * @param file     The file to write to.
 * @param issues   Issues arglist of report (e.g. under key "INFO").
 * @param hostname Name of the host.
 * @param port     Port 'name'.
 * @param type     Issue type. Holes will be printed in red.
 */
static void
html_output_print_issue_details (FILE* file, struct arglist* issues,
                                 char* hostname, char* port, issue_type type)
{
  struct arglist* issue = issues;
  char* desc;
  char* name;

  // Print a row with details for each issue in issues
  while (issue && issue->next)
    {
      if (strlen(issue->value))
        {
          fprintf (file, "   <tr>\n\t<td valign=top class=default width=\"10%%\">");
          switch (type)
            {
              case ISSUE_TYPE_FP:
                {
                  fprintf (file, "False Positive");
                  break;
                }
              case ISSUE_TYPE_NOTE:
                {
                  fprintf (file, "Informational");
                  break;
                }
              case ISSUE_TYPE_WARN:
                {
                  fprintf (file, "Warning");
                  break;
                }
              case ISSUE_TYPE_HOLE:
                {
                  fprintf (file, "<font color=red>Vulnerability</font>");
                  break;
                }
             default:
                {
                  fprintf (file, "Unknown Type");
                  break;
                }
            }
          fprintf (file, "</td>\n");

          // Port anchor
          name = html_output_portname_to_ahref (port, hostname);
          fprintf (file, "\t<td valign=top class=default width=\"10%%\"><a name=\"%s\"></a>%s</td>\n", name, port);
          efree (&name);

          // Print details of issue
          fprintf (file, "\t<td class=default width=\"80%%\">");
          desc = html_output_convert_cr_to_html (issue->value);
          html_output_print_data_with_links (file, desc, issue->name, FALSE);
          fprintf (file, "</td></tr>\n");
          efree (&desc);
        }
      issue = issue->next;
    } /* while (issue && issue->next) */
}

/**
 * @brief Wraps html_output_from_arg with no false-positive dropping.
 * 
 * Wrapper is needed in order to this function to be casteabel to
 * (output_func_t).
 * 
 * @param hosts Arglist with hosts containing issue arglists.
 * @param filename Name of file to write to.
 * @see html_output_from_arg
 */
int
arglist_to_html (struct arglist* hosts, char* filename)
{
  return html_output_from_arg (hosts, filename, FALSE, FALSE);
}

/* As pdf export works via intermediate html export, it might be worth looking
   at arglist_to_plainhtml (pdf_output.c), refactor and merge. */
/**
 * @brief Writes a report to an html file.
 * 
 * @param hosts        Arglist with hosts containing issue arglists.
 * @param filename     Name of file to write to.
 * @param drop_fp      If TRUE, False Positives will be dropped during conversion.
 * @param drop_no_info If TRUE, ports/services with no further issues (or only
 *                     LOG or DEBUG) will not be shown during conversion.
 * 
 * @return -1 if file could not be openend, 0 otherwise.
 */
int
html_output_from_arg (struct arglist* hosts, char* filename, gboolean drop_fp,
                      gboolean drop_no_info)
{
  FILE * file;
  struct arglist * h;

  if (!strcmp(filename, "-"))
    file = stdout;
  else
    file = fopen (filename, "w");

  if (!file)
    {
      show_error ("Could not create this file !");
      perror ("fopen ");
      return (-1);
    }

  /* Print the Style Sheet Opts and Report Summary */
  summary_to_file (file, hosts, drop_fp, drop_no_info);

  h = hosts;

  /* Print "Host list" */
  fprintf(file, "<table bgcolor=\"#a1a1a1\" border=0 cellpadding=0 cellspacing=0  width=\"60%%\">\n");
  fprintf(file, "<tbody><tr><td>\n   <table border=0 cellpadding=2 cellspacing=1 width=\"100%%\">\n");
  fprintf(file, "   <tbody>\n   <tr>\n\t<td class=title colspan=2>Host List</td></tr>\n");
  fprintf(file, "   <tr>\n\t<td class=sub width=\"60%%\">Host(s)</td>\n");
  fprintf(file, "\t<td class=sub width=\"40%%\">Possible Issue</td></tr>\n");
  /* Loop through hosts and print out their problems "Host List" */
  while(h && h->next)
    {
      int result = is_there_any_hole (h->value);
      // Put link on hostname if a vulnerability is present (plus condition
      // for hiding False Positives)
      if (result != 0 && !(drop_fp && result == FALSE_PRESENT))
        {
          char * href = html_output_portname_to_ahref (NULL, h->name);
          fprintf (file, "   <tr>\n\t <td class=default width=\"60%%\"><a href=\"#%s\">%s</a></td>\n", href, h->name);
          efree (&href);
        }
      else
        fprintf (file, "   <tr>\n\t <td class=default width=\"60%%\">%s</td>\n", h->name);

      if (result == HOLE_PRESENT)
        fprintf (file, "\t<td class=default width=\"40%%\"><font color=red>Security hole(s)</font></td></tr>\n");
      else if (result == WARNING_PRESENT)
        fprintf (file, "\t<td class=default width=\"40%%\">Security warning(s)</td></tr>\n");
      else if (result == NOTE_PRESENT)
        fprintf (file, "\t<td class=default width=\"40%%\">Security note(s)</td></tr>\n");
      else if (result == FALSE_PRESENT && drop_fp == FALSE)
        fprintf (file, "\t<td class=default width=\"40%%\">False positive(s)</td></tr>\n");
      else
        fprintf (file, "\t<td class=default width=\"40%%\">No noticeable information found</td></tr>\n");

      h = h->next;
    }
  fprintf (file, "</tbody></table></td></tr></tbody></table>\n\n");
  /* Finish printing Host list */

  /* Enter crazy loop for hosts and specific issues */
 while(hosts && hosts->next)
 {
  char * hostname;
  char * port;
  struct arglist * ports;
  char * href;
  char * name;
  hostname = hosts->name;
  int highest_severity;

  highest_severity = is_there_any_hole (hosts->value);

  // Skip Detail Tables if they would be empty
  if  (highest_severity == 0 || (highest_severity == FALSE_PRESENT && drop_fp))
    {
      hosts = hosts->next;
      continue;
    }

  href = html_output_portname_to_ahref (NULL, hostname);
  fprintf (file, "<a name=\"%s\"></a>\n", href);
  efree (&href);
  name = html_output_portname_to_ahref ("toc", hostname);
  fprintf (file, "<a name=\"%s\"></a>\n", name);
  efree (&name);

  fprintf(file, "<div align=\"left\"><font size=-2><a href=\"#toc\">[ return to top ]</a></font></div><br><br>\n");
  fprintf(file, "<table bgcolor=\"#a1a1a1\" border=0 cellpadding=0 cellspacing=0 width=\"60%%\">\n");
  fprintf(file, "<tbody><tr><td>\n   <table cellpadding=2 cellspacing=1 border=0 width=\"100%%\">\n");
  fprintf(file, "   <tbody>\n   <tr>\n\t<td class=title colspan=3>Analysis of Host</td></tr>\n");
  fprintf(file, "   <tr>\n\t<td class=sub width=\"20%%\">Address of Host</td>\n");
  fprintf(file, "\t<td class=sub width=\"30%%\">Port/Service</td>\n");
  fprintf(file, "\t<td class=sub width=\"30%%\">Issue regarding Port</td></tr>\n");


  ports = arg_get_value(hosts->value, "PORTS");
  if(ports)
  {
    html_output_print_port_table (file, ports, hostname, drop_fp, drop_no_info);

   fprintf(file, "<table bgcolor=\"#a1a1a1\" cellpadding=0 cellspacing=0 border=0 width=\"75%%\">\n");
   fprintf(file, "<tbody><tr><td>\n");
   fprintf(file, "\t<table cellpadding=2 cellspacing=1 border=0 width=\"100%%\">\n");
   fprintf(file, "\t\t<tr><td class=title colspan=3>Security Issues and Fixes: %s</td></tr>\n", hostname);
   fprintf(file, "\t\t<tr>\n\t\t<td class=sub width=\"10%%\">Type</td>\n");
   fprintf(file, "\t\t<td class=sub width=\"10%%\">Port</td>\n");
   fprintf(file, "\t\t<td class=sub width=\"80%%\">Issue and Fix</td></tr>\n");

   /* Write the summary of the open ports here */
   while(ports && ports->next)
   {
    struct arglist * report;
    struct arglist * info;
    struct arglist * note;
    struct arglist * false_positive;

    port = ports->name;
    report = arg_get_value(ports->value, "REPORT");
    html_output_print_issue_details (file, report, hostname, port, ISSUE_TYPE_HOLE);

   info = arg_get_value(ports->value, "INFO");
   html_output_print_issue_details (file, info, hostname, port, ISSUE_TYPE_WARN);

   false_positive = arg_get_value(ports->value, "FALSE");
   if(false_positive && drop_fp == FALSE)
     html_output_print_issue_details (file, false_positive, hostname, port, ISSUE_TYPE_FP);

   note = arg_get_value(ports->value, "NOTE");
   html_output_print_issue_details (file, note, hostname, port, ISSUE_TYPE_NOTE);

    ports = ports->next;
   }
  }
  fprintf(file, "</table></td></tr></tbody></table>\n");
  hosts = hosts->next;
 }

 // Print the mapping matrix if severity overrides were enabled for the report
 // export.
 if (Context->is_severity_mapped == TRUE)
  {
    int r = 0;
    int c = 0;
    fprintf (file, "<br><br>\n");
    fprintf (file, "<table bgcolor=\"#a1a1a1\" border=0 cellpadding=0 cellspacing=0 width=\"60%%\">\n");
    fprintf (file, "<tbody><tr><td>\n   <table cellpadding=2 cellspacing=1 border=0 width=\"100%%\">\n");
    fprintf (file, "   <tbody>\n   <tr>\n\t<td class=title colspan=7>Severity Filter Statistics</td></tr>\n");
    fprintf (file, "   <tr>\n\t<td class=sub width=\"14%%\">From/To</td>\n");

    // Horizontal captions
    for (c = 0; c < 6; c++)
      fprintf (file, "\t<td class=sub width=\"14%%\">%s</td>\n", priority_idx_to_str(c));
    fprintf (file, "\t</tr>\n");

    // Rows
    for (r = 0; r < 6; r++)
      {
        fprintf(file, "<tr>\n");
        fprintf(file, "<td class=sub>%s</td>", priority_idx_to_str(r));
        for (c = 0; c < 6; c++)
          {
            fprintf(file, "<td class=default style=\"text-align:center;vertical-align:middle;\">%d</td>\n", sev_mapping_matrix[r][c]);
          }
        fprintf(file, "</tr>\n");
      }

    fprintf (file, "</tr></tbody></table></td></tr></tbody></table>");
  }


 fprintf(file, "<hr>\n");
 fprintf(file, "<i>This file was generated by the <a href=\"http://www.openvas.org\">");
 fprintf(file, "OpenVAS</a> security scanner.</i>\n");
 fprintf(file, "</BODY>\n");
 fprintf(file, "</HTML>\n");
 fclose(file);
 return(0);
}

/**
 * @brief Prints the start of the html to report to file (including css,
 * @brief a small text, summary of the report).
 * 
 * @param file    File to write to.
 * @param host    "Report" arglist.
 * @param drop_fp If TRUE, user-defined False Positives will not appear in the
 *                summary. A note will be written to indicate that.
 * @param drop_fp If TRUE, issues with "No Information" will not appear in the
 *                summary. A note will be written to indicate that.
 */
static void
summary_to_file (FILE *file, struct arglist *hosts, gboolean drop_fp,
                 gboolean drop_ni)
{
 fprintf(file, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n");
 fprintf(file, "<HTML>\n");
 fprintf(file, " <HEAD>\n");
 fprintf(file, " <TITLE>OpenVAS Scan Report</TITLE>\n");
 fprintf(file, " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n");
 fprintf(file, " <style type=\"text/css\">\n");
 fprintf(file, " <!--\n");
 fprintf(file, "  BODY {\n\tBACKGROUND-COLOR: #ffffff\n }\n");
 fprintf(file, "  A {\tTEXT-DECORATION: none }\n");
 fprintf(file, "  A:visited {\tCOLOR: #0000cf; TEXT-DECORATION: none }\n");
 fprintf(file, "  A:link {\tCOLOR: #0000cf; TEXT-DECORATION: none }\n");
 fprintf(file, "  A:active {\tCOLOR: #0000cf; TEXT-DECORATION: underline }\n");
 fprintf(file, "  A:hover {\tCOLOR: #0000cf; TEXT-DECORATION: underline }\n");
 fprintf(file, "  OL {\tCOLOR: #333333; FONT-FAMILY: tahoma,helvetica,sans-serif }\n");
 fprintf(file, "  UL {\tCOLOR: #333333; FONT-FAMILY: tahoma,helvetica,sans-serif }\n");
 fprintf(file, "  P {\tCOLOR: #333333; FONT-FAMILY: tahoma,helvetica,sans-serif }\n");
 fprintf(file, "  BODY {\tCOLOR: #333333; FONT-FAMILY: tahoma,helvetica,sans-serif }\n");
 fprintf(file, "  TD {\tCOLOR: #333333; FONT-FAMILY: tahoma,helvetica,sans-serif }\n");
 fprintf(file, "  TR {\tCOLOR: #333333; FONT-FAMILY: tahoma,helvetica,sans-serif }\n");
 fprintf(file, "  TH {\tCOLOR: #333333; FONT-FAMILY: tahoma,helvetica,sans-serif }\n");
 fprintf(file, "  FONT.title {\tBACKGROUND-COLOR: white; COLOR: #363636; FONT-FAMILY: \
                  tahoma,helvetica,verdana,lucida console,utopia; FONT-SIZE: 10pt; FONT-WEIGHT: bold }\n");
 fprintf(file, "  FONT.sub {\tBACKGROUND-COLOR: white; COLOR: #000000; FONT-FAMILY: \
                  tahoma,helvetica,verdana,lucida console,utopia; FONT-SIZE: 10pt }\n");
 fprintf(file, "  FONT.layer {\tCOLOR: #ff0000; FONT-FAMILY: courrier,sans-serif,arial,helvetica; FONT-SIZE: 8pt; TEXT-ALIGN: left }\n");
 fprintf(file, "  TD.title {\tBACKGROUND-COLOR: #A2B5CD; COLOR: #555555; FONT-FAMILY: \
                  tahoma,helvetica,verdana,lucida console,utopia; FONT-SIZE: 10pt; FONT-WEIGHT: bold; HEIGHT: 20px; TEXT-ALIGN: right }\n");
 fprintf(file, "  TD.sub {\tBACKGROUND-COLOR: #DCDCDC; COLOR: #555555; FONT-FAMILY: \
                  tahoma,helvetica,verdana,lucida console,utopia; FONT-SIZE: 10pt; FONT-WEIGHT: bold; HEIGHT: 18px; TEXT-ALIGN: left }\n");
 fprintf(file, "  TD.content {\tBACKGROUND-COLOR: white; COLOR: #000000; FONT-FAMILY: \
                  tahoma,arial,helvetica,verdana,lucida console,utopia; FONT-SIZE: 8pt; TEXT-ALIGN: left; VERTICAL-ALIGN: middle }\n");
 fprintf(file, "  TD.default {\tBACKGROUND-COLOR: WHITE; COLOR: #000000; FONT-FAMILY: \
                  tahoma,arial,helvetica,verdana,lucida console,utopia; FONT-SIZE: 8pt; }\n");
 fprintf(file, "  TD.border {\tBACKGROUND-COLOR: #cccccc; COLOR: black; FONT-FAMILY: \
                  tahoma,helvetica,verdana,lucida console,utopia; FONT-SIZE: 10pt; HEIGHT: 25px }\n");
 fprintf(file, "  TD.border-HILIGHT {\tBACKGROUND-COLOR: #ffffcc; COLOR: black; FONT-FAMILY: \
                  verdana,arial,helvetica,lucida console,utopia; FONT-SIZE: 10pt; HEIGHT: 25px }\n");
 fprintf(file, "-->\n</style>\n");
 fprintf(file, "</HEAD>\n");
 fprintf(file, "<BODY>\n");
 fprintf(file, "<table bgcolor=\"#a1a1a1\" border=0 cellpadding=0 cellspacing=0 width=\"95%%\">\n");
 fprintf(file, "<tbody>\n\t<tr><td>\n<table border=0 cellpadding=2 cellspacing=1 width=\"100%%\">\n");
 fprintf(file, "\t<tbody>\n   <tr>\n");
 fprintf(file, "\t<td class=title>OpenVAS Scan Report</td></tr>\n");
 fprintf(file, "   <tr>\n\t<td class=content>This report gives details on hosts that were tested\n");
 fprintf(file, "\t\tand issues that were found. Please follow the recommended\n");
 fprintf(file, "\t\tsteps and procedures to eradicate these threats.\n");

 // Mention that a severity filter was applied (not seeing original data) if so
 if (Context->is_severity_mapped == TRUE)
  fprintf(file, "\n\t\t<br><br>A severity filter has been applied for the creation of "
                  "this document. Such a filter maps severities of issues as "
                  "reported from the security scanner to other severity levels, "
                  "e.g. to false positives.\n\t\t<br>"
                  "The filter is carefully specified by expert users and the "
                  "original scanner reports remain available unmodified."
                  "You will find statistics for the filter matches at the end of "
                  "the report.\n");

 if (drop_fp)
  fprintf(file, "\n\t\t<br><br>False Positives are not shown within this report.\n");

 if (drop_ni)
   fprintf(file, "\n\t\t<br><br>Ports/Services which would be listed with 'No Information' are not shown within this report.\n");

 fprintf(file, "</td></tr></tbody></table></td></tr></tbody></table><br>\n");
 fprintf(file, "\n");


 /* Write a (small) summary Hosts that are up, holes/warnings ect. */
 fprintf(file, "<table bgcolor=\"#a1a1a1\" border=0 cellpadding=0 cellspacing=0  width=\"60%%\">\n");
 fprintf(file, "<tbody><tr><td>\n");
 fprintf(file, "    <table border=0 cellpadding=2 cellspacing=1 width=\"100%%\">\n   <tbody>\n");
 fprintf(file, "    <tr>\n\t<td class=title colspan=2>Scan Details</td></tr>\n");
 fprintf(file, "    <tr>\n\t<td class=default width=\"60%%\">Hosts which were alive and responding during test</td>\n");
 fprintf(file, "\t<td class=default width=\"30%%\">%d</td></tr>\n",
                                arglist_length(hosts));

 fprintf(file, "   <tr>\n\t<td class=default width=\"60%%\">Number of security holes</td>\n");
 fprintf(file, "\t<td class=default width=\"30%%\">%d</td></tr>\n",
                                number_of_holes(hosts));
 fprintf(file, "   <tr>\n\t<td class=default width=\"60%%\">Number of security warnings</td>\n");
 fprintf(file, "\t<td class=default width=\"30%%\">%d</td></tr>\n",
                                number_of_warnings(hosts));
 fprintf(file, "   <tr>\n\t<td class=default width=\"60%%\">Number of security notes</td>\n");
 fprintf(file, "\t<td class=default width=\"30%%\">%d</td></tr>\n",
                                number_of_notes(hosts));
 if (drop_fp == FALSE)
  {
    fprintf(file, "   <tr>\n\t<td class=default width=\"60%%\">Number of false positives</td>\n");
    fprintf(file, "\t<td class=default width=\"30%%\">%d</td></tr>\n",
                                        number_of_false_positives(hosts));
  }

 fprintf(file, "</tbody></table></td></tr></tbody></table><br><br>\n");

 fprintf(file, "<a name=\"toc\"></a>\n");
}
