#
# This script was written by Thomas Reinke <reinke@securityspace.com>
#
# Copyright (c) 2005 E-Soft Inc. http://www.securityspace.com
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2
# 
# 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
# rpmcheck is intended to provide a quick way to verify that
# a given rpm, if it is installed, is up to date. The function
# isrpmvuln returns 0 if it is not installed or is installed
# but up to date, and returns 1 if it is installed and vulnerable


# Example call: isrpmvuln(pkg:"gnutls-utils", rpm:"gnutls-utils~1.4.1~3", rls:"FC6")

function isrpmvuln(pkg, rpm, rls) {
    # Check that we have the data for this release.
    kbrls = get_kb_item("ssh/login/release");
    if(kbrls!=rls) {
	return(0);
    }
    rpms = get_kb_item("ssh/login/rpms");
    if(!rpms) return(0);

    # Must include in the package search leading \n or ; to prevent
    # overly permissive search (e.g. search for 'ash' must not match 'bash')

    pat = string("[\n;](", pkg, "~[^;]+);");
#    pat = string(pkg, "~([^;]+);");
    matches = eregmatch(pattern:pat, string:rpms);
    if(isnull(matches)) {
	return(0);
    }
#security_note(0, data: "Comparing " + matches[1] + " against " + rpm);
    rc = revcomp(a:matches[1], b:rpm);
    if(rc<0) {
	norm_pkg = "";
	foreach comp (split(matches[1], sep: "~", keep:0)) {
	    norm_pkg = string(norm_pkg,"-",comp);
	}
	norm_pkg = substr(norm_pkg, 1);
	security_note(0, data: "Package " + pkg + " version " +
		norm_pkg + " is installed which is known to be vulnerable.");
	return(1);
    }
    return(0);
}
