Overview of pkg-lib-rpm.inc

Public Function Summary

Public functions are intended to be called by the code that imports this library.

Name Summary
isrpmvuln

Public Function Details

isrpmvuln

Named Parameters

pkg
rls
rpm

Code

function isrpmvuln(pkg, rpm, rls) {
    local_var a, b, kbrls, pat, matches, checkshorta, checkshortb, rc, norm_pkg, report;
    # Check that we have the data for this release.
    kbrls = get_kb_item("ssh/login/release");
    if(kbrls!=rls) {
	return NULL;
    }
    rpms = get_kb_item("ssh/login/rpms");
    if(!rpms) return NULL;

    # 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, "~[^;]+);");
    matches = eregmatch(pattern:pat, string:rpms);
    if(isnull(matches)) {
	return NULL;
    }
#security_message(0, data: "Comparing " + matches[1] + " against " + rpm);

    # Ok...revcomp handles almost all situations intellligently. But,
    # it can get caught on the following two string example:
    #    a:a="kernel~2.6.9~89.EL"; b="kernel~2.6.9~89.0.20.EL";
    # One would expect 'a' to be < (older than) 'b'.  However, in this
    # case revcomp differentiates the 'E' from the '0', and thinks that
    # that b is as a result older (lexicographically less than) a.
    # This is the only situation we've seen where this type of suffix
    # causes problems.  So, as a patch, we solve the problem locally 
    # BEFORE we call revcomp, by stripping from both strings the trailing
    # '.EL[0-9]*' suffix, but only if both strings have the identical suffix.
    # If we find other systems where this type of problem occurred, it may
    # make sense to consider if we should be stripping equal trailing strings
    # from the a/b parameters within revcomp. For now, though we'll do it here.

    a = matches[1];
    b = rpm;

    ## Spliting Package name and version
    ## Because the below replace _ with .(Dot) condition replaces
    ## _ in package name also
    asubstr = substr(a, strlen(pkg)+1, strlen(a));
    bsubstr = substr(b, strlen(pkg)+1, strlen(b));

    ## To replace _ with .(Dot)
    ## Because Version match fails in some case where version is having _(underscore)
    if(bsubstr =~ 'el[0-9]{1}_[0-9]{1}' && asubstr !~ 'el[0-9]{1}_[0-9]{1}')
      bsubstr = str_replace(string:bsubstr, find:'_', replace:'.');

    else if(asubstr =~ 'el[0-9]{1}_[0-9]{1}' && bsubstr !~ 'el[0-9]{1}_[0-9]{1}')
      asubstr = str_replace(string:asubstr, find:'_', replace:'.');

    ## Combining package name and version
    a = pkg + '~' + asubstr;
    b = pkg + '~' + bsubstr;

    checkshorta = eregmatch(pattern:"^(.*)[.]([Ee][Ll][0-9]*)$", string:a);
    checkshortb = eregmatch(pattern:"^(.*)[.]([Ee][Ll][0-9]*)$", string:b);
    if(!isnull(checkshorta) && !isnull(checkshortb)) {
	if(checkshorta[2]==checkshortb[2]) {
	    a = checkshorta[1];
	    b = checkshortb[1];
	}
    }

    if( eregmatch( pattern:"\.[0-9]{1}\.el[0-9]{1}", string:a ) && ! eregmatch( pattern:"\.[0-9]{1}\.el[0-9]{1}", string:b ) )
    {
      b = ereg_replace( pattern:"(\.el[0-9]{1})", replace:".0\1", string:b );
    }

    __pkg_match = TRUE;

    # Now proceed with the normal revision comparison
    rc = revcomp(a:a, b:b);
    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);
	report = "Package " + pkg + " version " +
		 norm_pkg + ' is installed which is known to be vulnerable.\n';
	return report;
    }
    return NULL;
}


		
top