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

📄 dansguardian.cpp

📁 一个UNIX/LINUX下的基于内容的过滤服务器源代码
💻 CPP
字号:
//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 <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <iostream>#include <arpa/inet.h>#include <cstdio>#include <string>#include <unistd.h>#include <cerrno>#include "dansguardian.hpp"#include "FatController.hpp"#include <syslog.h>#include <pwd.h>#include <fstream>#include <fcntl.h>#include "Socket.hpp"#include "SysV.hpp"#include <sys/time.h>#include <sys/resource.h>#ifdef __BSD	#include <sys/wait.h>#else	#include <wait.h>#endif#include <locale.h>#ifndef FD_SETSIZE#define FD_SETSIZE 256#endifOptionContainer o;bool isDaemonised;void ReadConfig(const char *configfile, int type) {    int rc = open(configfile, 0, O_RDONLY);    if (rc < 0) {        syslog(LOG_ERR, "Error opening %s", configfile);        cerr << "Error opening " << configfile << std::endl;        exit(1);  // could not open conf file for reading, exit with error    }    close (rc);    if (!o.read(configfile, type)) {        syslog(LOG_ERR, "%s","Error parsing the dansguardian.conf file or other DansGuardian configuration files");        cerr << "Error parsing the dansguardian.conf file or other DansGuardian configuration files" << std::endl;        exit(1);  // OptionContainer class had an error reading the conf or other files so exit with error    }}int main(int argc, char* argv[]) {    isDaemonised = false;    bool nodaemon = false;    std::string configfile = __CONFFILE;    srand(time(NULL));    SysV sysv;    int rc;    for (int i=1; i<argc; i++) {        int option = (argv[i][0] == '-')? argv[i][1] : 0;  // 0 will never be a valid option        switch (option) {            case 'P':                return 0;            case 'q':                ReadConfig(configfile.c_str(), 0);                return sysv.kill(o.pid_filename);            case 's':                ReadConfig(configfile.c_str(), 0);                return sysv.showPID(o.pid_filename);            case 'r':                ReadConfig(configfile.c_str(), 0);                return sysv.hup(o.pid_filename);            case 'g':                ReadConfig(configfile.c_str(), 0);                return sysv.usr1(o.pid_filename);            case 'v':                std::cout << "DansGuardian 2.8.0.6" << std::endl;                return 0;            case 'N':                nodaemon = true;                break;            case 'c':                if (++i < argc) {                    configfile = argv[i];                    break;                }            case 'h':                std::cout << "Usage: " << argv[0] << " [{-c ConfigFileName|-v|-P|-h|-N|-q|-s|-r|-g}]" << std::endl;                std::cout << "  -v gives the version number." << std::endl;                std::cout << "  -P displays the name and version of any 3rd party extensions compiled in." << std::endl;                std::cout << "  -h gives this message." << std::endl;                std::cout << "  -c allows you to specify a different configuration file location." << std::endl;                std::cout << "  -N Do not go into the background." << std::endl;                std::cout << "  -q causes DansGuardian to kill any running copy." << std::endl;                std::cout << "  -s shows the parent process PID." << std::endl;                std::cout << "  -r closes all connections and reloads config files by issuing a HUP," << std::endl;                std::cout << "     but this does not reset the maxchildren option." << std::endl;                std::cout << "  -g gently restarts by not closing all current connections and only reloads\n     filter group config files by issuing a USR1." << std::endl;                if (option == 'h')                    return 0;  // they asked for the help                return 1;  // they need help        }    }    // Set current locale for proper character conversion    setlocale(LC_ALL,"");    ReadConfig(configfile.c_str(), 2);    if (sysv.amIRunning(o.pid_filename)) {        syslog(LOG_ERR, "%s","I seem to be running already!");        std::cerr << "I seem to be running already!" << std::endl;        return 1;  // can't have two copies running!!    }    if (nodaemon) {        o.no_daemon = 1;    }    if ((o.max_children+ 6) > FD_SETSIZE) {        syslog(LOG_ERR, "%s","maxchildren option in dansguardian.conf has a value too high.");        std::cerr << "maxchildren option in dansguardian.conf has a value too high." << std::endl;        std::cerr << "Dammit Jim, I'm a filtering proxy, not a rabbit." << std::endl;        return 1;  // we can't have rampant proccesses can we?    }    int pidfilefd = sysv.openPIDFile(o.pid_filename);  // we have to open/create                                                // as root before drop privs    if (pidfilefd < 0) {        syslog(LOG_ERR, "%s","Error creating/opening pid file.");        std::cerr << "Error creating/opening pid file:" << o.pid_filename << std::endl;        return 1;    }    unsigned int rootuid;  // prepare a struct for use later    rootuid = geteuid();    o.root_user = rootuid;    struct passwd *st;  // prepare a struct    if ((st = getpwnam(o.daemon_user_name.c_str())) != 0) {  // find uid for proxy user        o.proxy_user = st->pw_uid;        o.proxy_group = st->pw_gid;        rc = setgid(o.proxy_group);  // change to rights of proxy user group		                     // i.e. low - for security        if (rc == -1) {            syslog(LOG_ERR, "%s","Unable to setgid()");	    std::cerr << "Unable to setgid()" << std::endl;	    return 1;  // setgid failed for some reason so exit with error        }        #ifdef __HPUX         rc = setreuid(-1, st->pw_uid);        #else	 rc = seteuid(o.proxy_user);  // need to be euid so can su back                                     // (yes it negates but no choice)	#endif	if (rc == -1) {	    syslog(LOG_ERR, "%s","Unable to seteuid()");	    std::cerr << "Unable to seteuid()" << std::endl;	    return 1;  // seteuid failed for some reason so exit with error        }    }    else {        syslog(LOG_ERR, "%s","Unable to getpwnam() - does the proxy user exist?");	cerr << "Unable to getpwnam() - does the proxy user exist?" << std::endl;	cerr << "Proxy user looking for is '" << o.daemon_user_name << "'" << std::endl;	return 1;  // was unable to lockup the user id from passwd	           // for some reason, so exit with error    }    if (o.no_logger == 0) {        ofstream logfiletest(o.log_location.c_str(), ios::app);        if (logfiletest.fail()) {            syslog(LOG_ERR, "%s","Error opening/creating log file. (check ownership and access rights).");            std::cout << "Error opening/creating log file. (check ownership and access rights)." << std::endl;            std::cout << "I am running as " << o.daemon_user_name << " and I am trying to open " << o.log_location << std::endl;            return 1;  // opening the log file for writing failed        }        logfiletest.close();    }    FatController f;  // Thomas The Tank Engine    while (true) {        if (!f.testProxy(o.proxy_ip, o.proxy_port, false)) {            sleep(4);  // give the proxy more time (work around squid bug)            if (!f.testProxy(o.proxy_ip, o.proxy_port, false)) {                sleep(4);                if (!f.testProxy(o.proxy_ip, o.proxy_port, true)) {                    return 1;  // could not connect to the proxy so exit with error                           // with no proxy we can not continue                }            }        }        rc = f.controlIt(pidfilefd);                             // its a little messy, but I wanted to split                             // all the ground work and non-daemon stuff                             // away from the daemon class                             // However the line is not so fine.        if (rc == 2) {            // In order to re-read the conf files and create cache files            // we need to become root user again            #ifdef __HPUX             rc = setreuid(-1, rootuid);            #else             rc = seteuid(rootuid);            #endif            if (rc == -1) {                syslog(LOG_ERR, "%s","Unable to seteuid() to read conf files.");                #ifdef DGDEBUG                    std::cerr << "Unable to seteuid() to read conf files." << std::endl;                #endif                return 1;            }            #ifdef DGDEBUG                std::cout << "About to re-read conf file." << std::endl;            #endif            o.reset();            if (!o.read(configfile.c_str(), 2)) {                syslog(LOG_ERR, "%s","Error re-parsing the dansguardian.conf file or other DansGuardian configuration files");                #ifdef DGDEBUG                    std::cerr << "Error re-parsing the dansguardian.conf file or other DansGuardian configuration files" << std::endl;                #endif                return 1;                   // OptionContainer class had an error reading the conf or	           // other files so exit with error            }            #ifdef DGDEBUG                std::cout << "conf file read." << std::endl;            #endif            if (nodaemon) {                o.no_daemon = 1;            }            while(waitpid(-1, NULL, WNOHANG) > 0) {}  // mop up defunts            #ifdef __HPUX             rc = setreuid(-1, st->pw_uid);            #else             rc = seteuid(st->pw_uid);  // become low priv again            #endif            if (rc == -1) {	        syslog(LOG_ERR, "%s","Unable to re-seteuid()");	        #ifdef DGDEBUG                    std::cerr << "Unable to re-seteuid()" << std::endl;                #endif	        return 1;  // seteuid failed for some reason so exit with error            }            continue;        }        if (rc > 0) {            if (!isDaemonised) {                std::cerr << "Exiting with error" << std::endl;            }            syslog(LOG_ERR, "%s","Exiting with error");            return rc;  // exit returning the error number        }        return 0;  // exit without error    }}

⌨️ 快捷键说明

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