예제 #1
0
// Test whether or not a particular request's incoming/outgoing data should be scanned.
// This is an early-stage (request headers only) test; no other info is known about
// the actual data itself when this is called.
int CSPlugin::willScanRequest(const String &url, const char *user, int filtergroup,
    const char *ip, bool post, bool reconstituted, bool exception, bool bypass)
{
    // Most content scanners only deal with original, unmodified content
    if (reconstituted) {
#ifdef DGDEBUG
        std::cout << "willScanRequest: ignoring reconstituted data" << std::endl;
#endif
        return DGCS_NOSCAN;
    }

    // Deal with POST file uploads conditionally, but subject only to the "scanpost"
    // option, not to the domain & URL lists - uploading files does not have the same
    // implications as downlaoding them.
    if (post) {
        if (scanpost) {
#ifdef DGDEBUG
            std::cout << "willScanRequest: I'm interested in uploads" << std::endl;
#endif
            return DGCS_NEEDSCAN;
        } else {
#ifdef DGDEBUG
            std::cout << "willScanRequest: Not interested in uploads" << std::endl;
#endif
            return DGCS_NOSCAN;
        }
    }

    String urld(HTTPHeader::decode(url));
    urld.removeWhiteSpace();
    urld.toLower();
    urld.removePTP();
    String domain, tempurl, foundurl, path;
    unsigned int fl;
    if (urld.contains("/")) {
        domain = urld.before("/");
        path = "/" + urld.after("/");
        path.hexDecode();
        path.realPath();
    } else {
        domain = urld;
    }

    // Don't scan the web server which hosts the access denied page
    if (((o.fg[filtergroup]->reporting_level == 1) || (o.fg[filtergroup]->reporting_level == 2))
        && domain.startsWith(o.fg[filtergroup]->access_denied_domain)) {
#ifdef DGDEBUG
        std::cout << "willScanRequest: ignoring our own webserver" << std::endl;
#endif
        return DGCS_NOSCAN;
    }

    // exceptionvirussitelist
    tempurl = domain;
    while (tempurl.contains(".")) {
        if (exceptionvirussitelist.findInList(tempurl.toCharArray()) != NULL) {
#ifdef DGDEBUG
            std::cout << "willScanRequest: ignoring exception virus site" << std::endl;
#endif
            return DGCS_NOSCAN; // exact match
        }
        tempurl = tempurl.after("."); // check for being in higher level domains
    }
    if (tempurl.length() > 1) {
        // allows matching of .tld
        tempurl = "." + tempurl;
        if (exceptionvirussitelist.findInList(tempurl.toCharArray()) != NULL) {
#ifdef DGDEBUG
            std::cout << "willScanRequest: ignoring exception virus site" << std::endl;
#endif
            return DGCS_NOSCAN; // exact match
        }
    }

    // exceptionvirusurllist
    tempurl = domain + path;
    if (tempurl.endsWith("/")) {
        tempurl.chop(); // chop off trailing / if any
    }
    while (tempurl.before("/").contains(".")) {
        char *i = exceptionvirusurllist.findStartsWith(tempurl.toCharArray());
        if (i != NULL) {
            foundurl = i;
            fl = foundurl.length();
            if (tempurl.length() > fl) {
                unsigned char c = tempurl[fl];
                if (c == '/' || c == '?' || c == '&' || c == '=') {
#ifdef DGDEBUG
                    std::cout << "willScanRequest: ignoring exception virus URL" << std::endl;
#endif
                    return DGCS_NOSCAN; // matches /blah/ or /blah/foo but not /blahfoo
                }
            } else {
#ifdef DGDEBUG
                std::cout << "willScanRequest: ignoring exception virus URL" << std::endl;
#endif
                return DGCS_NOSCAN; // exact match
            }
        }
        tempurl = tempurl.after("."); // check for being in higher level domains
    }

#ifdef DGDEBUG
    std::cout << "willScanRequest: I'm interested" << std::endl;
#endif
    return DGCS_NEEDSCAN;
}
예제 #2
0
// Test whether or not a particular request's incoming/outgoing data should be scanned.
// This is a later-stage test; info is known about the actual data itself when this is called.
int CSPlugin::willScanData(const String &url, const char *user, int filtergroup, const char *ip, bool post,
    bool reconstituted, bool exception, bool bypass, const String &disposition, const String &mimetype,
    off_t size)
{
    //exceptionvirusmimetypelist
    if (mimetype.length() > 2) {
        if (exceptionvirusmimetypelist.findInList(mimetype.toCharArray()) != NULL) {
#ifdef DGDEBUG
            std::cout << "willScanData: ignoring exception MIME type (" << mimetype.c_str() << ")" << std::endl;
#endif
            return DGCS_NOSCAN; // match
        }
    }

    //exceptionvirusextensionlist
    String extension;
    if (disposition.length() > 2) {
// If we have a content-disposition, determine file extension from that
#ifdef DGDEBUG
        std::cout << "disposition: " << disposition << std::endl;
#endif
        std::string::size_type start = disposition.find("filename=");
        if (start != std::string::npos) {
            start += 9;
            char endchar = ';';
            if (disposition[start] == '"') {
                endchar = '"';
                ++start;
            }
            std::string::size_type end = disposition.find(endchar, start);
            if (end != std::string::npos)
                extension = disposition.substr(start, end - start);
            else
                extension = disposition.substr(start);
        }
        while (extension.contains(".")) {
            extension = extension.after(".");
        }
        extension = "." + extension;
#ifdef DGDEBUG
        std::cout << "extension from disposition: " << extension << std::endl;
#endif
    } else {
        // Otherwise, determine it from the URL
        String urld(HTTPHeader::decode(url)), path;
        urld.removeWhiteSpace();
        urld.toLower();
        urld.removePTP();

        if (urld.contains("/")) {
            path = urld.after("/");
            path.hexDecode();
            path.realPath();
        }

        if (!path.contains("?")) {
            extension = path;
        } else if (mimetype.contains("application/")) {
            extension = path;
            if (extension.contains("?")) {
                extension = extension.before("?");
            }
        }
#ifdef DGDEBUG
        std::cout << "extension from URL: " << extension << std::endl;
#endif
    }
    if (extension.contains(".")) {
        if (exceptionvirusextensionlist.findEndsWith(extension.toCharArray()) != NULL) {
#ifdef DGDEBUG
            std::cout << "willScanData: ignoring exception file extension (" << extension.c_str() << ")" << std::endl;
#endif
            return DGCS_NOSCAN; // match
        }
    }

#ifdef DGDEBUG
    std::cout << "willScanData: I'm interested" << std::endl;
#endif
    return DGCS_NEEDSCAN;
}
예제 #3
0
// test whether or not a request should be scanned based on sent & received headers
int CSPlugin::scanTest(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip)
{
	char *i;

	//exceptionvirusmimetypelist
	String mimetype(docheader->getContentType());
#ifdef DGDEBUG
	std::cout<<"mimetype: "<<mimetype<<std::endl;
#endif
	i = exceptionvirusmimetypelist.findInList(mimetype.toCharArray());
	if (i != NULL) {
		return DGCS_NOSCAN;  // match
	}

	String disposition(docheader->disposition());
#ifdef DGDEBUG
	std::cout<<"disposition: "<<disposition<<std::endl;
#endif
	String url(requestheader->url());
	String urld(requestheader->decode(url));
	urld.removeWhiteSpace();
	urld.toLower();
	urld.removePTP();
	String domain, tempurl, foundurl, path, extension;
	unsigned int fl;
	if (urld.contains("/")) {
		domain = urld.before("/");
		path = "/" + urld.after("/");
		path.hexDecode();
		path.realPath();
	} else {
		domain = urld;
	}

	// don't scan our web server
	if (((o.fg[filtergroup]->reporting_level == 1) || (o.fg[filtergroup]->reporting_level == 2)) && domain.startsWith(o.fg[filtergroup]->access_denied_domain)) {
		return DGCS_NOSCAN;
	}

	//exceptionvirusextensionlist
	if (disposition.length() > 2) {
		extension = disposition;
		while (extension.contains(".")) {
			extension = extension.after(".");
		}
		extension = "." + extension;
	} else {
		if (!path.contains("?")) {
			extension = path;
		}
		else if (mimetype.contains("application/")) {
			extension = path;
			if (extension.contains("?")) {
				extension = extension.before("?");
			}
		}
	}
#ifdef DGDEBUG
	std::cout<<"extension: "<<extension<<std::endl;
#endif
	if (extension.contains(".")) {
		i = exceptionvirusextensionlist.findEndsWith(extension.toCharArray());
		if (i != NULL) {
			return DGCS_NOSCAN;  // match
		}
	}

	// exceptionvirussitelist
	tempurl = domain;
#ifdef DGDEBUG
	std::cout<<"domain: "<<domain<<std::endl;
#endif
	while (tempurl.contains(".")) {
		i = exceptionvirussitelist.findInList(tempurl.toCharArray());
		if (i != NULL) {
			return DGCS_NOSCAN;  // exact match
		}
		tempurl = tempurl.after(".");  // check for being in higher level domains
	}
	if (tempurl.length() > 1) {	// allows matching of .tld
		tempurl = "." + tempurl;
		i = exceptionvirussitelist.findInList(tempurl.toCharArray());
		if (i != NULL) {
			return DGCS_NOSCAN;  // exact match
		}
	}

	// exceptionvirusurllist
	tempurl = domain + path;
	if (tempurl.endsWith("/")) {
		tempurl.chop();  // chop off trailing / if any
	}
	while (tempurl.before("/").contains(".")) {
		i = exceptionvirusurllist.findStartsWith(tempurl.toCharArray());
		if (i != NULL) {
			foundurl = i;
			fl = foundurl.length();
			if (tempurl.length() > fl) {
				unsigned char c = tempurl[fl];
				if (c == '/' || c == '?' || c == '&' || c == '=') {
					return DGCS_NOSCAN;  // matches /blah/ or /blah/foo but not /blahfoo
				}
			} else {
				return DGCS_NOSCAN;  // exact match
			}
		}
		tempurl = tempurl.after(".");  // check for being in higher level domains
	}

#ifdef DGDEBUG
	std::cout << "URL " << url << " is going to need AV scanning." << std::endl;
#endif

	return DGCS_NEEDSCAN;
}