Oracle Java Runtime Environment (JRE) Detection (Unix)

2013-02-22T00:00:00
ID SUN_JAVA_JRE_INSTALLED_UNIX.NASL
Type nessus
Reporter Tenable
Modified 2019-02-05T00:00:00

Description

One or more instances of Oracle's (formerly Sun's) Java Runtime Environment (JRE) are installed on the remote host. This may include private JREs bundled with the Java Development Kit (JDK).

Notes: - This plugin does not detect non-Oracle JRE instances such as OpenJDK, GCJ, IBM Java, etc.

  • To discover instances of JRE that are not in PATH, or installed via a package manager, thorough tests must be enabled.

                                        
                                            #TRUSTED 1cc75028a68ecc53ac5c5c8a6ead8609774bb9632057b0c972971893268b4a977c87dfcfc0327a6d8f27887bbdf8dbddfc381f81fab42b23556393157609e696d3449156e0bdb51f8e11f66b14df442a631c9e5725507a1b9538dd296a7675e7a6e8a636ca5fcbd9ce23ed7087dfd1987c729c147c944b6b89b1fbf3b6d40163e64ee61099a78132dc2e09297bd59e208dd413f78e524a7cb26075da3678c6fb57cc33bd8ab555cb329cf716185ca10b9d514ca7aff4088d338ba1c8220eec8ad4b49cb9764d2244316bba56899c8735902047c0210a9b1ce8dc1a2b00d14cb0db5e274b2dfb1c32f5ed2bb51bc0f3e7cbacaf3503a349cd807dc4c20f782beacf3061604ec520d50bae9d82bbb90af51dc2a2374e917382a95ca55692075696ccf5f9762c5b3a8a86835cbc987866b57c6f76f3d55cfa89484e8a9bfeea98cf4f11136b4647a48a90692c9a06a54e0e1301aeaaefa72de76fa1b454755dcf4a6511852dda20204c70b3c56c524afe21a38dc91efa57543ac006fa85493e5921cb1667a49786d6d945ad4ad2014e876a76591278c310a66ff1afbd792df0de8f35b9e50b67de2d14e5a782cce6e9910bd0e96039b378b8b0016e1fb1f69d2a42dbb39e065ac11067c3c2f77862c98136958bef7ed7dee9981d252ff8ec9c1a9288d4fcb3ee3d3af077c8a8675141d1ba58fee6f71a974d3946fb5872e69561e7

#
# (C) Tenable Network Security, Inc.
#


include("compat.inc");


if (description)
{
  script_id(64815);
  script_version("1.60");
  script_set_attribute(attribute:"plugin_modification_date", value:"2019/02/05");

  script_name(english:"Oracle Java Runtime Environment (JRE) Detection (Unix)");
  script_summary(english:"Checks for Oracle/Sun JRE installs.");

  script_set_attribute(attribute:"synopsis", value:
"The Java runtime environment is installed on the remote Unix host.");
  script_set_attribute(attribute:"description", value:
"One or more instances of Oracle's (formerly Sun's) Java Runtime
Environment (JRE) are installed on the remote host. This may include
private JREs bundled with the Java Development Kit (JDK).

Notes:
  
  - This plugin does not detect non-Oracle JRE instances such
    as OpenJDK, GCJ, IBM Java, etc.

  - To discover instances of JRE that are not in PATH, 
    or installed via a package manager, thorough tests 
    must be enabled.");
  script_set_attribute(attribute:"see_also", value:"https://www.oracle.com/technetwork/java/index.html");
  script_set_attribute(attribute:"solution", value:"n/a");
  script_set_attribute(attribute:"risk_factor", value:"None");

  script_set_attribute(attribute:"plugin_publication_date", value:"2013/02/22");

  script_set_attribute(attribute:"plugin_type", value:"local");
  script_set_attribute(attribute:"cpe", value:"cpe:/a:oracle:jre");
  script_set_attribute(attribute:"agent", value:"unix");
  script_end_attributes();

  script_category(ACT_GATHER_INFO);
  script_family(english:"General");

  script_copyright(english:"This script is Copyright (C) 2013-2019 and is owned by Tenable, Inc. or an Affiliate thereof.");

  script_dependencies("ssh_get_info.nasl", "oracle_enum_products_nix.nbin");
  script_require_keys("Host/local_checks_enabled");
  script_timeout(640); # Allow find a bit more time than the default

  exit(0);
}

include("audit.inc");
include("global_settings.inc");
include("ssh_func.inc");
include("telnet_func.inc");
include("hostlevel_funcs.inc");
include("misc_func.inc");
include("install_func.inc");
include("find_cmd.inc");
include("sh_commands_find.inc");

if(sshlib::get_support_level() >= sshlib::SSH_LIB_SUPPORTS_COMMANDS)
  enable_ssh_wrappers();
else disable_ssh_wrappers();

##
# Checks to see if a java install is bundled with an Oracle Product
#
# @remark This function basically checks to see if javapath contains any known
#         ohome path.
#
# @param javapath string absolute path to the java binary to check
#
# @returns TRUE if javapath is bundled in an Oracle application, FALSE if not
##
function oracle_bundled_java(javapath)
{
  # Optimization: if no Oracle products are installed it can't be bundled
  if(!get_kb_item("Oracle/Products/Installed"))
    return FALSE;
  local_var sqlq = "SELECT path FROM oracle_homes";
  local_var sqlr = query_scratchpad(sqlq);
  local_var row  = NULL;
  if(isnull(sqlr))
    return FALSE;
  foreach row (sqlr)
  {
    if(row["path"] >< javapath)
      return TRUE;
  }
  return FALSE;
}

# Simple wrapper to make run_cmd_template a drop in replacement for
# info_send_cmd
function run_cmd_template_wrapper(template,args)
{
  local_var resp;
  resp = run_cmd_template(template:template,args:args);
  if (resp['error'] == HLF_OK)
    resp = resp['data'];
  else
    resp = NULL;
  return resp;
}

# Attempts to resolve a symlinks "true" path via namei if
# namei is not available we will use ls and follow up to
# 5 links, if item is not a symlink or cannot be resolved
# in 5 traversals it is returned unchanged otherwise 
# the true path is returned.
function resolve_symlink(item)
{
  local_var sympath,buf2,line,lines,count,path;
  local_var old_sympath, pattern, match;

  # If the path / item doesn't start with / 
  # then its an error like "find : cycle detect"
  # ect ...
  if(item !~ "^/(.*)$")
    return item;

  sympath = '';
  old_sympath =  item;
  buf2 = info_send_cmd(cmd:"namei " + item);
  if (buf2 && 'not found' >!< buf2 && "segmentation fault" >!< tolower(buf2))
  {
    lines = split(buf2, keep:FALSE);
    foreach line (lines)
    {
      # symlinks start with 'l'
      if (preg(pattern:'^(\\s)+l .*', string:line))
      {
        sympath = ereg_replace(pattern:'^(\\s)+l [^>]+> (.*)$', string:line, replace:"\2");
        if(sympath !~ "^/")
        {
          match = pregmatch(pattern:"^\s+l ([^>]+) .> (.*)", string:line);
          if(!isnull(match))
          {
             pattern = match[1];
             sympath = ereg_replace(pattern:pattern, string:old_sympath, replace:match[2]);
             sympath = ereg_replace(pattern:'//', replace:'/', string:sympath);
          }
        }
        old_sympath = sympath;
      }
    }
    if (sympath) item = chomp(sympath);
  }
  # Not all hosts support namei. In those cases,
  # just use ls to follow the symlink
  else
  {
    # Go up to 5 deep on the symlinks
    count = 0;
    while (count < 5)
    {
      path = item;
      path = ereg_replace(pattern:"^(.*)/$",string:path,replace:"\1"); # Strip trailing /
      buf2 = info_send_cmd(cmd:"ls -l " + path);
      # No buf : there was an error return original item
      if (!buf2)
        break;
      #  Not a symlink : we're done following
      if (buf2 !~ "^l.*")
        break;

      sympath = ereg_replace(pattern:'^l[^>]+> (.*)', string:buf2, replace:"\1");
      # Some more mangling in case the symlink points to ../*
      # so we can get the correct path
      # For each ../ remove one level from the path until ../ is no longer
      # in the symlink path or we are at the root directory for path
      if (sympath =~ '^../')
      {
        while (sympath =~ '^../')
        {
          path = ereg_replace(pattern:'^(/.*/).*/.*', string:path, replace:"\1");
          if (path == '/')
          {
            sympath = sympath - '../';
            path = path + sympath;
            break;
          }
          sympath = substr(sympath, 3);
        }
        path = path + sympath;
        item = chomp(path);
      }
      # Absolute sympath
      else if(sympath =~ "^/(.*)$")
      {
        item = chomp(sympath);
      }
      # Symlink relative to it's parent dir
      else
      {
        path = ereg_replace(pattern:'^(.*)/[^/]+$',string:path, replace:"\1");
        item = chomp(path)+"/"+chomp(sympath);
      }
      count++;
    }
  }
  return item;
}

function safe_java_version(path,java,shell_path)
{
  local_var chkorcl_ptrn, version_ptrn, # grep patterns
            version_ptrn_escaped,       # an escaped style of ver pattern (use with grep -o -a styles)
            chkorcl_cmdt, version_cmdt, # command template to run
            chkorcl_file, version_file, # files to check
            chkorcl_resp, version_resp, # responses from commands
            exclude_cmdt, exclude_resp, # variables use to check if the rt.jar contains "openjdk / icedt / ect"
            exclude_ptrn,
            version,                    # parsed version
            chkjlib_resp,               # response from running ls path+"/lib/"
            libpath,                    # the path where the lib is, needed to find runtime
            chkorcl_exists_resp;        # the response from running ls for certain files existence

  if(isnull(shell_path))
    shell_path = "/bin/bash";

  # Figure out if we're dealing with JDK or JRE
  libpath = path+"/lib/";
  chkjlib_resp = run_cmd_template_wrapper(template:shell_path+' -c "ls $1$/rt.jar" 2>&1',args:make_list(libpath));
  # If no rt.jar, look for modules instead
  if("no such file or directory" >< tolower(chkjlib_resp))
  {
    chkjlib_resp = run_cmd_template_wrapper(template:shell_path+' -c "ls $1$/modules" 2>&1',args:make_list(libpath));
    if("no such file or directory" >< tolower(chkjlib_resp))
    {
      # If no rt.jar and no modules, probably is JDK, so look lower down into its jre dir
      libpath = path+"/jre/lib/";
      chkjlib_resp = run_cmd_template_wrapper(template:shell_path+' -c "ls $1$/rt.jar" 2>&1',args:make_list(libpath));
      if("no such file or directory" >< tolower(chkjlib_resp))
      {
        # If no rt.jar in JDK, try modules
        chkjlib_resp = run_cmd_template_wrapper(template:shell_path+' -c "ls $1$/modules" 2>&1',args:make_list(libpath));
        if("no such file or directory" >< tolower(chkjlib_resp))
        {
          # No rt.jar and no modules in either of JDK nor JRE ... done here
          return FALSE;
        }
        else
        {
          # JDK without rt.jar
          chkorcl_file = libpath+"modules";
          chkorcl_ptrn = "'Copyright.*Oracle.*affiliates'";
        }
      }
      else
      {
        # JDK with rt.jar
        chkorcl_file = libpath+"rt.jar";
        chkorcl_ptrn = "'Implementation-Vendor: .*'";
      }
    }
    else
    {
      # JRE without rt.jar
      chkorcl_file = libpath+"modules";
      chkorcl_ptrn = "'Copyright.*Oracle.*affiliates'";
    }
  }
  else
  {
    # JRE with rt.jar
    chkorcl_file = libpath+"rt.jar";
    chkorcl_ptrn = "'Implementation-Vendor: .*'";
  }

  # Parse files for version information
  # The runtime (rt.jar) contains oracle / sun specific strings, the java binary
  # contains the version string itself
  #version_ptrn = "'[0-9]\.[0-9]\{1,2\}\.[0-9]\{1,2\}\(_[0-9]\{1,3\}\)\{0,1\}-b[0-9]\{1,2\}'";
  # e.g., 1.7.0_111 or 9.0.4+11 
  version_ptrn         = "'[0-9]+\.[0-9]{1,2}\.[0-9]{1,2}((_[0-9]{1,3}){0,1}-b[0-9]{1,2}|\+[0-9]+)'";
  version_ptrn_escaped = "'[0-9]\+\.[0-9]\{1,2\}\.[0-9]\{1,2\}\(\(_[0-9]\{1,3\}\)\{0,1\}-b[0-9]\{1,2\}\|+[0-9]\{1,\}\)'";
  exclude_ptrn = "-i '(OpenJDK Runtime Environment)'"; # IcedT / OpenJDK sometimes, erroneous 

  # HPUX does not have "-m" for grep
  if (get_kb_item("Host/HP-UX/version"))
  {
    chkorcl_cmdt = shell_path+" -c "+'"'+"strings $1$ | grep "+chkorcl_ptrn+'" | head -n 1';
    version_cmdt = shell_path+" -c "+'"'+"strings $1$ | grep -E "+version_ptrn+'" | head -n 1';
    exclude_cmdt = shell_path+" -c "+'"'+"strings $1$ | grep "+exclude_ptrn+'" | head -n 1';
  }
  else
  {
    chkorcl_cmdt = shell_path+" -c "+'"'+"strings $1$ | grep -m 1 "+chkorcl_ptrn+'"';
    version_cmdt = shell_path+" -c "+'"'+"strings $1$ | grep -E -m 1 "+version_ptrn+'"';
    exclude_cmdt = shell_path+" -c "+'"'+"strings $1$ | grep -m 1 "+exclude_ptrn+'"';
  }

  chkorcl_exists_resp = run_cmd_template_wrapper(template:shell_path+' -c "ls $1$" 2>&1',args:make_list(chkorcl_file));
  if ("no such file or directory" >< tolower(chkorcl_exists_resp))
    chkorcl_file = libpath+"modules";
  chkorcl_exists_resp = run_cmd_template_wrapper(template:shell_path+' -c "ls $1$" 2>&1',args:make_list(chkorcl_file));

  version_file = java;
  # Stuff without strings by default
  if ( get_kb_item("Host/Ubuntu/release") ||
       get_kb_item("Host/Debian/release") ||
       get_kb_item("Host/SuSE/release")
  )
  {
    version_cmdt  = shell_path+" -c "+'"'+"grep -o -a "+version_ptrn_escaped+" $1$"+'"';
    chkorcl_cmdt  = shell_path+" -c "+'"'+"grep -o -a "+chkorcl_ptrn+" $1$"+'"';
    exclude_cmdt  = shell_path+" -c "+'"'+"grep -o -a "+exclude_ptrn+" $1$"+'"';
  }
  # Use egrep on solaris and hpux
  if (
    get_kb_item("Host/Solaris/Version") ||
    get_kb_item("Host/Solaris11/Version") ||
    get_kb_item("Host/HP-UX/version")
  )
  {
    if (!get_kb_item("Host/HP-UX/version"))
      chkorcl_ptrn = "'Implementation-Vendor: .*'";

    version_ptrn = "'[0-9]+\.[0-9]+\.[0-9]+(_[0-9]+)?-b[0-9]+'";
    chkorcl_cmdt = shell_path+" -c "+'"'+"strings $1$ | egrep "+chkorcl_ptrn+'"';
    version_cmdt = shell_path+" -c "+'"'+"strings $1$ | egrep "+version_ptrn+'"';
    exclude_cmdt = shell_path+" -c "+'"'+"strings $1$ | egrep "+exclude_ptrn+'"';
  }

  version_resp = run_cmd_template_wrapper(template:version_cmdt,args:make_list(version_file));
  chkorcl_resp = run_cmd_template_wrapper(template:chkorcl_cmdt,args:make_list(chkorcl_file));
  exclude_resp = run_cmd_template_wrapper(template:exclude_cmdt,args:make_list(chkorcl_file));

  #In some cases, the java binary is stripped out of java by namei
  #If that happened, try sending the command again with /bin/java appended
  if (isnull(version_resp) || (!isnull(version_resp) && 'is a directory' >< tolower(version_resp)))
  {
    java += '/bin/java';
    version_file += '/bin/java';
    version_resp = run_cmd_template_wrapper(template:version_cmdt,args:make_list(version_file));
  }

  #In some cases (web apps) it's rt.pack not rt.jar
  if (!isnull(chkorcl_resp) && 'no such file' >< tolower(chkorcl_resp))
  {
    chkorcl_file = libpath+"rt.pack";
    chkorcl_resp = run_cmd_template_wrapper(template:chkorcl_cmdt,args:make_list(chkorcl_file));
    exclude_resp = run_cmd_template_wrapper(template:exclude_cmdt,args:make_list(chkorcl_file));
  }

  if("OpenJDK Runtime Environment" >< tolower(exclude_resp))
  {
    return FALSE;
  }

  if(!version_resp)
  {
    return FALSE;
  }

  # Oracle bought Sun around ~ Java v1.5
  if(chkorcl_resp !~ "(Sun Microsystems, Inc.|Oracle Corporation|Copyright.*Oracle)")
  {
    return FALSE;
  }

  # Parse and format version
  if ("_" >< version_resp)
    version = pregmatch(pattern:"(\d+\.\d+\.\d+(_\d+)?)-b\d+", string:version_resp);
  else
  {
    # 9.0.4 and up, version looks like :
    # 9.0.4+11 and so forth
    matches = pregmatch(pattern:"^([0-9]+)\.([0-9]+)\.([0-9]+)", string:version_resp);
    if (!matches)
      return FALSE;

    version = make_list("astring","1." + matches[1] + "." + matches[2] + '_' + matches[3]);
  }

  if(isnull(version))
    return FALSE;

  version = version[1];
  if(version =~ "^\d+\.\d+\.\d+$")
    version += "_0";

  # Java bin location may have been updated: return both java and version
  return make_array("version", version, "java", java);
}

##
# Attempts to find java actively running in /proc/
##
function find_paths_in_proc()
{
  local_var fnd = make_array();
  local_var cmd = "ls -l /proc/*/exe 2> /dev/null | awk '/java/'";
  local_var buf = info_send_cmd(cmd:cmd);
  local_var line = NULL;

  if("command not found" >< buf)
    return make_list();

  buf = split(buf);
  foreach line (buf)
  {
    line = pregmatch(pattern:'exe[ \t]+->[ \t]+(.*java)$', string:line);
    if(!empty_or_null(line))
      fnd[line[1]] = TRUE;
  }
  return fnd;
}

#################
# Setup Section
################
app = "Oracle Java";
dirs_to_check = make_list("/opt/", "/usr/");
shell_path = "/bin/bash";
# OSes unlikely to have bash
if(
  get_kb_item("Host/FreeBSD/release") ||
  get_kb_item("Host/HP-UX/version")
)
  shell_path = "/bin/sh";
# OSes that frequently have find timeout because of large
# directory structures in /usr/
if(get_kb_item("Host/FreeBSD/release"))
  dirs_to_check = make_list("/usr/lib/", "/usr/lib34/", "/usr/lib64/", "/usr/bin/", "/usr/sbin/", "/usr/local/", "/opt/");

# Only the following OSes are currently supported
unsupported = TRUE;
if ( get_kb_item("Host/CentOS/release") ||
     get_kb_item("Host/Debian/release") ||
     get_kb_item("Host/FreeBSD/release") ||
     get_kb_item("Host/Gentoo/release") ||
     get_kb_item("Host/HP-UX/version") ||
     get_kb_item("Host/Mandrake/release") ||
     get_kb_item("Host/RedHat/release") ||
     get_kb_item("Host/Slackware/release") ||
     get_kb_item("Host/Solaris/Version") ||
     get_kb_item("Host/Solaris11/Version") ||
     get_kb_item("Host/SuSE/release") ||
     get_kb_item("Host/Ubuntu/release") ||
     get_kb_item("Host/AIX/version") ||
     get_kb_item("Host/EulerOS/release")
  ) unsupported = FALSE;

if (unsupported) exit(0, "Unix Java checks are not supported on the remote OS at this time.");

# We may support other protocols here
if ( islocalhost() )
{
 if ( ! defined_func("pread") ) audit(AUDIT_FN_UNDEF,"pread");
 info_t = INFO_LOCAL;
}
else
{
 sock_g = ssh_open_connection();
 if (! sock_g) audit(AUDIT_FN_FAIL,"ssh_open_connection");
 info_t = INFO_SSH;
}

info = "";
path_already_seen = make_array();
buffers = make_nested_array(
  'located_via_find', NULL,
  'located_via_which', NULL
);
buf = NULL;
partial_find_results = FALSE;
found_with_proc = make_array();
is_proc_path = FALSE;

if (thorough_tests)
{

  buf = find_cmd(
    path_patterns : make_list("*/java"),
    start         : join(dirs_to_check, sep:" "),
    maxdepth      : NULL,
    timeout       : 320, # Half our total time
    exit_on_fail  : TRUE
  );

  # Find command returned something but also timedout
  # results may be partial
  partial_find_results = (!empty_or_null(buf[1]) && timedout);

  # find_cmd failed or timedout without returning anything
  if(buf[0] != FIND_OK || (empty_or_null(buf[1]) && timedout))
  {
    #if targetting a HP-UX system, we need to use a slightly different command
    if (get_kb_item("Host/HP-UX/version"))
    {
      command = make_list(dirs_to_check, '-xautofs', '-tenb_fstype_exclusions', '-tenb_path_exclusions', '-type', 'l', '-name', 'java', '-print');
    }
    else
    {
      command = make_list(dirs_to_check, '-xautofs', '-tenb_fstype_exclusions', '-tenb_path_exclusions', '-type', 'f', '-name', 'java', '-print');
    }

    buf = sh_commands::find(args:command);

    if (buf[0] == sh_commands::CMD_OK)
    {
      buf = buf[1];
    }
    else if (buf[0] == sh_commands::CMD_TIMEOUT)
    {
      partial_find_results = TRUE;
      buf = buf[1];
    }
    else
    {
      # Failed find so return empty since these are only part of the results
      partial_find_results = TRUE;
      buf = "";
    }
  }
  else
  {
    # All good use these results
    buf = buf[1];
  }

  # Also append any directories found via inspection of proc
  found_with_proc = find_paths_in_proc();
  foreach proc_path (keys(found_with_proc))
  {
    if(proc_path >!< buf)
      buf = proc_path+'\n'+buf;
    else
      found_with_proc[proc_path] = FALSE; # Already found this path ignore reporting the note about /proc/
  }
}
buffers['located_via_find'] = buf;
buf = NULL;

# Check for java in PATH (thorough or not)
if (
  get_kb_item("Host/HP-UX/version") ||
  get_kb_item("Host/Solaris/Version") ||
  get_kb_item("Host/Solaris11/Version") ||
  get_kb_item("Host/FreeBSD/release") ||
  get_kb_item("Host/AIX/version")
) command = "which java";
else command = "which -a java";
buf = info_send_cmd(cmd:command);
buffers['located_via_which'] = buf;

# Nothing in both ; done
if (
  empty_or_null(buffers['located_via_find']) &&
  empty_or_null(buffers['located_via_which'])
)
  audit(AUDIT_NOT_INST, app);

foreach located_via (keys(buffers))
{
  buf = buffers[located_via];
  if ('no java in' >!< buf && 'Command not found' >!< buf)
  {
    buf = chomp(buf);
    array = split(buf);
    foreach item (array)
    {
      item = chomp(item);
      # Did we find this path using /proc/ or find ?
      if(found_with_proc[item])
        is_proc_path = TRUE;
      else
        is_proc_path = FALSE;

      ##############################################################
      # Parse / normalize install path
      #
      item = resolve_symlink(item:item);

      path = item;
      # attempt to identify the install directory
      path = ereg_replace(pattern:"\/solr\/jre\/bin\/.*java$" , replace:"/", string:path);
      path = ereg_replace(pattern:"\/runtime\/jre\/bin\/.*java$" , replace:"/", string:path);
      path = ereg_replace(pattern:"\/jre\/bin\/.*java$" , replace:"/", string:path);
      if (path !~ '/usr/bin/java')
        path = ereg_replace(pattern:"\/bin\/.*java$" , replace:"/", string:path);
      path = chomp(path);
      # path could also be a symlink: try to resolve it
      path = resolve_symlink(item:path);
      # ensure that path ends in /
      if(path !~ "^.*/$") path += "/";

      # Optimization: skip paths containing openjdk
      # this isn't guaranteed to skip all openjdk
      # installs but at least we won't run expensive
      # commands against these dirs. And gcj. 
      if ("openjdk" >< tolower(path) ||
          "gcj" >< tolower(path)
      )
        continue;

      ############################################################
      # Retrieve version information
      resp = FALSE;

      # Obtain version from located binaries
      resp = safe_java_version(path:path,java:item,shell_path:shell_path);

      # No version found for path / item -> next path / item
      if(!resp)
        continue;

      item = resp['java'];
      ver_formatted = resp['version'];

      ############################################################
      # More Path Normalization
      #
      # Note: we'd like to be more specific in the path
      # for things like Coldfusion, Signacert, tarantella,
      # so just remove not so much of the path
      if (
        "/solr/" >< item       ||
        "/runtime/" >< item    ||
        "/signacert/" >< item
      )
        path = ereg_replace(pattern:"\/bin\/.*java$" , replace:"/", string:item);

      if ("/tarantella/" >< item)
      {
        matches = pregmatch(
          string  :item,
          pattern :"^(\/.*tarantella\/.*\/jdk\.[^/]+\/(jre\/)?)bin\/java$",
          icase   : TRUE
        );
        if (matches)
          path = matches[1];
      }

      # path + version already seen -> next path / item
      if (path_already_seen[path+ver_formatted]++)
        continue;

      ############################################################
      # Determine if the managed
      #
      managed = 0;
      cmdtarg = make_list(item, path);
      foreach cmdtarg_piece (cmdtarg)
      {
        cmdtarg_piece = make_list(preg_replace(pattern:"(^.*)(\/$)", replace:"\1", string:cmdtarg_piece));

        # check to see if the install was installed via a native package management software
        if (get_kb_item("Host/RedHat/rpm-list") || get_kb_item("Host/SuSE/rpm-list") || get_kb_item("Host/CentOS/rpm-list"))
        {
          buf2 = run_cmd_template_wrapper(template:'rpm -qf $1$',args:cmdtarg_piece);
          if ( buf2 )
            if ( ('-sun' >< buf2 || '-oracle' >< buf2 || '-fcs' >< buf2) && ("is not owned by any package" >!< buf2) && ("No such file or directory" >!< buf2) )
            {
              managed = 1;
              break;
            }
        }
        else if ( get_kb_item("Host/HP-UX/swlist") )
        {
          # this may be a bit slow, eventually we may need to find a faster solution
          buf2 = sh_commands::find('/var/adm/sw/products', '-name', 'INFO', '-exec', 'grep -il "' + cmdtarg_piece[0] + '" \'{}\' \\;');
          if (buf2[0] == sh_commands::CMD_OK)
          {
            if ( "/var/adm/sw/products/" >< buf2[1] )
            {
              managed = 1;
              break;
            }
          }
        }
        else if ( get_kb_item("Host/Solaris11/pkg-list") )
        {
          buf2 = run_cmd_template_wrapper(template:'pkg search -l -H -o pkg.name "$1$" && echo MANAGED',args:cmdtarg_piece);
          if ( buf2 )
            if ( "MANAGED" >< buf2 )
            {
              managed = 1;
              break;
            }
        }
        else if ( get_kb_item("Host/Solaris/showrev") )
        {
          buf2 = run_cmd_template_wrapper(template:'pkgchk -l -p "$1$"',args:cmdtarg_piece);
          if ( buf2 )
            if ( cmdtarg_piece[0] >< buf2 )
            {
              managed = 1;
              break;
            }
        }
        else if ( get_kb_item("Host/AIX/lslpp") )
        {
          buf2 = run_cmd_template_wrapper(template:'lslpp -w "$1$"',args:cmdtarg_piece);
          if ( buf2 )
            if ( item >< buf2 )
            {
              managed = 1;
              break;
            }
        }
      }

      # Register install information
      kb_str = "Host/Java/JRE/";
      if(oracle_bundled_java(javapath:path))
        kb_str += "Bundled/";
      else if (managed == 1)
        kb_str += "Managed/";
      else
        kb_str += "Unmanaged/";
      set_kb_item(name:kb_str+ver_formatted, value:path);

      if (!managed)
        register_install(
          app_name:app,
          path:path,
          version:ver_formatted,
          display_version:ver_formatted,
          cpe:"cpe:/a:oracle:jre",
          extra_no_report:make_array('managed', managed)
        );
      else
        register_install(
          app_name:app,
          path:path,
          version:ver_formatted,
          display_version:ver_formatted,
          cpe:"cpe:/a:oracle:jre",
          extra_no_report:make_array('managed', managed),
          extra:make_array('Managed by OS', "True")
        );

      if(is_proc_path)
      {
         info +=
        '\n  Note    : This install was discovered by checking the currently'+
        '\n            running processes on the system, and it may not always'+
        '\n            be reported in future scans.';
      }
      info += '\n';
    }
  }
}
if (info_t == INFO_SSH) ssh_close_connection();

# Report what we found.
if (info)
{
  set_kb_item(name:"Host/Java/JRE/Installed", value:TRUE);

  if(thorough_tests && partial_find_results)
  {
    info +=
    '\n' +
    'Note: During execution it appears that the find command timed' +
    'out and may have only returned partial results.\n\n';
  }

  report_installs(app_name:app, extra:info);
}
else audit(AUDIT_NOT_INST, app);