⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connectionhandler.cpp

📁 一个UNIX/LINUX下的基于内容的过滤服务器源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//Please refer to http://dansguardian.org/?page=copyright2//for the license for this code.//Written by Daniel Barron (daniel@jadeb//.com).//For support go to http://groups.yahoo.com/group/dansguardian//  This program is free software; you can redistribute it and/or modify//  it under the terms of the GNU General Public License as published by//  the Free Software Foundation; either version 2 of the License, or//  (at your option) any later version.////  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA#include "autoconf/platform.h"#include <syslog.h>#include "ImageContainer.hpp"#include "ConnectionHandler.hpp"#include "DataBuffer.hpp"#include "Socket.hpp"#include "UDSocket.hpp"#include "Ident.hpp"#ifdef __BSD	#include <sys/wait.h>#else	#include <wait.h>#endif#include "FDTunnel.hpp"#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <cstdio>#include <algorithm>#include <iostream>#include <netdb.h>#include <cstdlib>#include <unistd.h>#include <sys/time.h>#ifdef __GCCVER3    #include <istream>#else    #include <istream.h>#endifextern OptionContainer o;void ConnectionHandler::handleConnection(int peerfd, String ip, int port) {    Socket peerconn;    peerconn.close();    peerconn.setFD(peerfd);    struct timeval thestart;    struct timezone notused;    gettimeofday(&thestart, &notused);    peerconn.setTimeout(10);    HTTPHeader header;  // to hold the incoming client request header    header.setTimeout(10);  // set a timeout as we don't want blocking 4 eva    HTTPHeader docheader;  // to hold the returned page header from proxy    docheader.setTimeout(20);    DataBuffer docbody;  // to hold the returned page    docbody.setTimeout(120);    bool waschecked = false;  // flags    bool wasrequested = false;    bool isexception = false;    bool isourwebserver = false;    bool wasclean = false;    bool cachehit = false;    bool forceauthrequest = false;    bool isbypass = false;    bool iscookiebypass = false;    int bypasstimestamp = 0;    bool ispostblock = false;    bool pausedtoobig = false;    if (o.preemptive_banning == 0) {            forceauthrequest = true;    }    std::string mimetype = "-";    String url;    String urld;    String urldomain;    std::string exceptionreason;  // to hold the reason for not blocking    int docsize = 0;  // to store the size of the returned document for loggin    Ident ident;  // for holding    std::string clientip = ip.toCharArray();  // hold the clients ip    #ifdef DGDEBUG  // debug stuff surprisingly enough        std::cout << "got connection" << std::endl;        std::cout << clientip << std::endl;    #endif    Socket proxysock;  // to hold connection to proxy    try {        // connect to proxy        int rc = proxysock.connect(o.proxy_ip, o.proxy_port);        if (rc) {            #ifdef DGDEBUG                std::cerr << "Error connecting to proxy" << std::endl;            #endif            syslog(LOG_ERR, "%s","Error connecting to proxy");            return;  // if we can't connect to the proxy, there is no point                 // in continuing        }        header.in(&peerconn);  // get header from client        url = header.url();        urld = header.decode(url);        if (url.after("://").contains("/")) {            urldomain = url.after("//").before("/");        }        else {            urldomain = url.after("//");        }        if (header.malformedURL(url)) {            // checks for bad URLs to prevent security hole            try { // writestring throws exception on error/timeout                peerconn.writeString("HTTP/1.0 400 Bad Request\n");                peerconn.writeString("Content-Type: text/html\n\n");                peerconn.writeString("<HTML><HEAD><TITLE>DansGuardian - 400 Bad Request</TITLE></HEAD><BODY><H1>DansGuardian - 400 Bad Request</H1> ");                peerconn.writeString(o.language_list.getTranslation(200));                // The requested URL is malformed.                peerconn.writeString("</BODY></HTML>\n");            } catch (exception& e) {}            try {                proxysock.close();  // close connection to proxy            } catch (exception& e) {}            return;        }        if (o.use_xforwardedfor == 1) {            std::string xforwardip = header.getXForwardedForIP();            if (xforwardip.length() > 6) {                clientip = xforwardip;            }            #ifdef DGDEBUG                std::cout << "using x-forwardedfor:" << clientip << std::endl;            #endif        }        std::string clientuser = ident.getUsername(&header, &clientip, port);                                                   // extract username        #ifdef DGDEBUG            std::cout << "About to determine group" << std::endl;        #endif        int filtergroup = determineGroup(&clientuser);        if (filtergroup < 0) {            filtergroup = determineGroup(&clientip);        }        if (filtergroup < 0) {            filtergroup = 0; //default group - one day configurable?        }        #ifdef DGDEBUG            std::cout << "filtergroup:" << filtergroup << std::endl;        #endif        if (o.forwarded_for == 1) {            header.addXForwardedFor(clientip);  // add squid-like entry        }        if ((*o.fg[filtergroup]).bypass_mode != 0) {            #ifdef DGDEBUG                std::cout << "About to check for bypass..." << std::endl;            #endif            bypasstimestamp = header.isBypassURL(&url, (*o.fg[filtergroup]).magic.c_str(), clientip.c_str());            if (bypasstimestamp > 0) {                #ifdef DGDEBUG                    std::cout << "Bypass URL match" << std::endl;                #endif                header.chopBypass(url);                url = header.url();                urld = header.decode(url);                if (bypasstimestamp > 1) {  // not expired                    isbypass = true;                    exceptionreason = o.language_list.getTranslation(606);                }            }            else if (header.isBypassCookie(&urldomain, (*o.fg[filtergroup]).cookie_magic.c_str(), clientip.c_str())) {                #ifdef DGDEBUG                    std::cout << "Bypass cookie match" << std::endl;                #endif                iscookiebypass = true;                isbypass = true;                exceptionreason = o.language_list.getTranslation(607);            }            #ifdef DGDEBUG                std::cout << "Finished bypass checks." << std::endl;            #endif        }        if (isbypass) {            #ifdef DGDEBUG                std::cout << "Bypass activated!" << std::endl;            #endif        }        else if (o.inipexceptions(&clientip)) {  // admin pc            isexception = true;            exceptionreason = o.language_list.getTranslation(600);            // Exception client IP match.        }        else if (o.inuserexceptions(&clientuser)) { // admin user            isexception = true;            exceptionreason = o.language_list.getTranslation(601);            // Exception client user match.        }        else if ((*o.fg[filtergroup]).inexceptions(urld)) {  // allowed site            if ((*o.fg[0]).iswebserver(url)) {                isourwebserver = true;            }            else {                isexception = true;                exceptionreason = o.language_list.getTranslation(602);                // Exception site match.            }        }        else if ((*o.fg[filtergroup]).inurlexceptions(urld)) {  // allowed url            isexception = true;            exceptionreason = o.language_list.getTranslation(603);            // Exception url match.        }        #ifdef DGDEBUG            std::cout << "extracted url:" << urld << std::endl;        #endif	if ( (isourwebserver || isexception || iscookiebypass)	    // don't filter exception and local web server	    // Cookie bypass so don't need to add cookie so just CONNECT	    && !o.inBannedIPList(&clientip)		// bad users pc	    && !o.inBannedUserList(&clientuser) ) { 	// bad user	    proxysock.readyForOutput(10);  // exception on timeout or error            header.out(&proxysock);  // send proxy the request            try {                FDTunnel fdt;  // make a tunnel object                // tunnel from client to proxy and back                fdt.tunnel(proxysock.getFD(), peerconn.getFD()); // not expected to exception                docsize = fdt.throughput;                if (!isourwebserver) {  // don't log requests to the web server                    decideHowToLog(clientuser, clientip, url.toCharArray(), header.port, exceptionreason, header.requesttype().toCharArray(), docsize, o.ll, false, isexception, o.log_exception_hits, false, &thestart, cachehit, 200, mimetype);                }            } catch (exception& e) {}            try {                proxysock.close();  // close connection to proxy            } catch (exception& e) {}            return;  // connection dealt with so exit        }        NaughtyFilter checkme;  // our filter object        checkme.filtergroup = filtergroup;        char* i;        // Improved IF structure as suggested by AFN        if ((!forceauthrequest || header.requesttype().startsWith("CONNECT")) && !isbypass) {            // if its a connect and we don't do filtering on it now then            // it will get tunneled and not filtered.  We can't tunnel later            // as its ssl so we can't see the return header etc            // So preemptive banning is forced on with ssl unfortunately.            // It is unlikely to cause many problems though.            requestChecks(&header, &checkme, &urld, &clientip, &clientuser, filtergroup, &ispostblock);        }        if (!checkme.isItNaughty && header.requesttype().startsWith("CONNECT")) {            // can't filter content of CONNECT            proxysock.readyForOutput(10);  // exception on timeout or error            header.out(&proxysock);  // send proxy the request            try {                FDTunnel fdt;  // make a tunnel object                // tunnel from client to proxy and back

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -