Beispiel #1
0
static int libwrap_ask(struct request_info *r, int fd)
{
    int a;
    struct sockaddr_storage sin;
    socklen_t len = sizeof(sin);

    /* XXX: old FreeBSD didn't fill sockaddr correctly against AF_UNIX */
    sin.ss_family = AF_UNIX;

    /* is this a connection from the local host? */
    if (getpeername(fd, (struct sockaddr *) &sin, &len) == 0) {
	if (((struct sockaddr *)&sin)->sa_family == AF_UNIX) {
	    return 1;
	}
    }
    
    /* i hope using the sock_* functions are legal; it certainly makes
       this code very easy! */
    request_set(r, RQ_FILE, fd, 0);
    sock_host(r);

    a = hosts_access(r);
    if (!a) {
	syslog(deny_severity, "refused connection from %s", eval_client(r));
    }

    return a;
}
static void
twist_option(char *value, struct request_info *request)
{
    if (dry_run != 0) {
	dry_run = 0;
    } else {
	if (resident > 0)
	    tcpd_jump("twist option in resident process");

	syslog(deny_severity, "twist %s to %s", eval_client(request), value);

	/* Before switching to the shell, set up stdin, stdout and stderr. */

#define maybe_dup2(from, to) ((from == to) ? to : (close(to), dup(from)))

	if (maybe_dup2(request->fd, 0) != 0 ||
	    maybe_dup2(request->fd, 1) != 1 ||
	    maybe_dup2(request->fd, 2) != 2) {
	    tcpd_warn("twist_option: dup: %m");
	} else {
	    if (request->fd > 2)
		close(request->fd);
	    (void) execl("/bin/sh", "sh", "-c", value, (char *) 0);
	    tcpd_warn("twist_option: /bin/sh: %m");
	}

	/* Something went wrong: we MUST terminate the process. */
	clean_exit(request);
    }
}
Beispiel #3
0
static void wrap_log_request_denied(int priority,
    struct request_info *request) {
  pr_log_pri(priority, MOD_WRAP_VERSION ": refused connection from %s",
    eval_client(request));

  /* done */
  return;
}
Beispiel #4
0
static void wrap_log_request_denied(int severity,
    struct request_info *request) {
  int priority;

  /* Mask off the facility bits. */
  priority = (severity & PR_LOG_PRIMASK);

  pr_log_pri(priority, MOD_WRAP_VERSION ": refused connection from %s",
    eval_client(request));

  /* done */
  return;
}
Beispiel #5
0
/*
 * send_stats:
 *	Accept a connection to the statistics port, and emit
 *	the stats.
 */
static void
send_stats(void)
{
	FILE	*fp;
	int	s;
	struct sockaddr_in	sockstruct;
	socklen_t	socklen;
	struct request_info ri;
	int	flags;

	/* Accept a connection to the statistics socket: */
	socklen = sizeof sockstruct;
	s = accept(Status, (struct sockaddr *) &sockstruct, &socklen);
	if (s < 0) {
		if (errno == EINTR)
			return;
		logx(LOG_ERR, "accept");
		return;
	}

	/* Check for access permissions: */
	request_init(&ri, RQ_DAEMON, "huntd", RQ_FILE, s, 0);
	fromhost(&ri);
	if (hosts_access(&ri) == 0) {
		logx(LOG_INFO, "rejected connection from %s", eval_client(&ri));
		close(s);
		return;
	}

	/* Don't allow the writes to block: */
	flags = fcntl(s, F_GETFL, 0);
	flags |= O_NDELAY;
	(void) fcntl(s, F_SETFL, flags);

	fp = fdopen(s, "w");
	if (fp == NULL) {
		logit(LOG_ERR, "fdopen");
		(void) close(s);
		return;
	}

	print_stats(fp);

	(void) fclose(fp);
}
Beispiel #6
0
int
TcpAcceptConnection(int sock, struct sockaddr_storage *addr, int block)
{
	int new_sock;
	socklen_t size = sizeof(struct sockaddr_storage);

/* Accept incoming connection */

	memset(addr, 0, sizeof(*addr));
	if ((new_sock = accept(sock, (struct sockaddr *)addr, &size)) < 0) {
		Perror("%s: accept", __FUNCTION__);
		return (-1);
	}
#ifdef USE_WRAP
	if (Enabled(&gGlobalConf.options, GLOBAL_CONF_TCPWRAPPER)) {
		struct request_info req;

		request_init(&req, RQ_DAEMON, "mpd", RQ_FILE, new_sock, NULL);
		fromhost(&req);
		if (!hosts_access(&req)) {
			Log(LG_ERR, ("refused connection (tcp-wrapper) from %s",
			    eval_client(&req)));
			close(new_sock);
			return (-1);
		}
	}
#endif

	if (!block) {
		(void)fcntl(new_sock, F_SETFD, 1);
		if (fcntl(new_sock, F_SETFL, O_NONBLOCK) < 0) {
			Perror("%s: fcntl", __FUNCTION__);
			return (-1);
		}
	}
/* Done */

	return (new_sock);
}
char *my_eval_client(struct request_info *req)
{
  return eval_client(req);
}
int main(int argc, char* argv[])
{
    boost::mpi::environment env(argc, argv);
    boost::mpi::communicator world;

    int delay;
    std::string time_fname;
    namespace po = boost::program_options;
    po::options_description desc("Allowed options");
    desc.add_options()
    ("help,h", "produce help message")
    ("delay,d", po::value<int>(&delay)->default_value(10), "delay in function eval to test speedup of parallelisation for objective functions of different computational cost (OF eval time in seconds")
    ("time,t", po::value<std::string>(&time_fname)->default_value("timer.txt"), "File to write elapsed time for optimiser too");
    po::variables_map vm;
    po::store(po::command_line_parser(argc, argv).
              options(desc).run(), vm);
    po::notify(vm);

    DelayFON eval(delay);

    std::stringstream timer_info;
    boost::scoped_ptr<boost::timer::auto_cpu_timer> t((boost::timer::auto_cpu_timer *) nullptr);

    if (world.rank() == 0)
    {
        std::ofstream ofs(time_fname.c_str());
        if (ofs.is_open())
        {
            t.reset(new boost::timer::auto_cpu_timer(timer_info, 3));
        }
        else
        {
            std::cerr << "Error: Could not open file for writing time elapsed for search, using std::cout";
            t.reset(new boost::timer::auto_cpu_timer(3));
        }


        //create evaluator server
        ParallelEvaluatePopServer eval_server(env, world, eval.getProblemDefinitions());

        // The random number generator
        typedef std::mt19937 RNG;
        unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
        RNG rng(seed);

        // The optimiser
        int max_gen = 10;
        NSGAII<RNG> optimiser(rng, eval_server);
        MaxGenCheckpoint max_gen_stop(max_gen);
        optimiser.add_checkpoint(max_gen_stop);

//        optimiser.visualise();

        // Initialise population
        int pop_size = 128	;
        PopulationSPtr pop = intialisePopulationRandomDVAssignment(pop_size, eval.getProblemDefinitions(), rng);

        // Run the optimisation
        optimiser(pop);


        t.reset((boost::timer::auto_cpu_timer *) nullptr);
        if (ofs.is_open())
        {
            ofs << timer_info.str();
            ofs.close();
        }
        std::cout << timer_info.str() << std::endl;

    }
    else
    {
        // create evaluator client
        ParallelEvaluatePopClient eval_client(env, world, eval.getProblemDefinitions(), eval);
        eval_client();
    }

}
Beispiel #9
0
int main(int argc, char *argv[])
{
    struct request_info request;
    char    path[MAXPATHNAMELEN];

    /* Attempt to prevent the creation of world-writable files. */

#ifdef DAEMON_UMASK
    umask(DAEMON_UMASK);
#endif

    /*
     * If argv[0] is an absolute path name, ignore REAL_DAEMON_DIR, and strip
     * argv[0] to its basename.
     */

    if (argv[0][0] == '/') {
	strlcpy(path, argv[0], sizeof path);
	argv[0] = strrchr(argv[0], '/') + 1;
    } else {
	snprintf(path, sizeof path, "%s/%s", REAL_DAEMON_DIR, argv[0]);
    }

    /*
     * Open a channel to the syslog daemon. Older versions of openlog()
     * require only two arguments.
     */

#ifdef LOG_MAIL
    (void) openlog(argv[0], LOG_PID, FACILITY);
#else
    (void) openlog(argv[0], LOG_PID);
#endif

    /*
     * Find out the endpoint addresses of this conversation. Host name
     * lookups and double checks will be done on demand.
     */

    request_init(&request, RQ_DAEMON, argv[0], RQ_FILE, STDIN_FILENO, 0);
    fromhost(&request);

    /*
     * Optionally look up and double check the remote host name. Sites
     * concerned with security may choose to refuse connections from hosts
     * that pretend to have someone elses host name.
     */

#ifdef PARANOID
    if (STR_EQ(eval_hostname(request.client), paranoid))
	refuse(&request);
#endif

    /*
     * The BSD rlogin and rsh daemons that came out after 4.3 BSD disallow
     * socket options at the IP level. They do so for a good reason.
     * Unfortunately, we cannot use this with SunOS 4.1.x because the
     * getsockopt() system call can panic the system.
     */

#ifdef KILL_IP_OPTIONS
    fix_options(&request);
#endif

    /*
     * Check whether this host can access the service in argv[0]. The
     * access-control code invokes optional shell commands as specified in
     * the access-control tables.
     */

#ifdef HOSTS_ACCESS
    if (!hosts_access(&request))
	refuse(&request);
#endif

    /* Report request and invoke the real daemon program. */

    syslog(allow_severity, "connect from %s", eval_client(&request));
    closelog();
    (void) execv(path, argv);
    syslog(LOG_ERR, "error: cannot execute %s: %m", path);
    clean_exit(&request);
    /* NOTREACHED */
}
int main(int argc, char* argv[])
{
    boost::filesystem::path working_dir = boost::filesystem::initial_path();
    boost::mpi::environment env(argc, argv);
    boost::mpi::communicator world;

    MinMaxFON test_problem;
    
    if (world.rank() == 0)
    {
        //create evaluator server

        //create evaluator server
        std::string eval_log_fname("mpi_msgs.txt");
        std::ofstream eval_strm(eval_log_fname.c_str());
        ParallelEvaluatePopServerNonBlocking eval_server(env, world, test_problem.getProblemDefinitions());
        if (eval_strm.is_open())
        {
            eval_server.log(ParallelEvaluatorBase::LVL1, eval_strm);
        }



        
        std::stringstream timer_info;
        boost::scoped_ptr<boost::timer::auto_cpu_timer> t((boost::timer::auto_cpu_timer *) nullptr);
        std::string time_fname("run_time_fon.txt");
        std::ofstream ofs(time_fname.c_str());
        if (ofs.is_open())
        {
            t.reset(new boost::timer::auto_cpu_timer(timer_info, 3));
        }
        else
        {
            std::cerr << "Error: Could not open file for writing time elapsed for search, using std::cout";
            t.reset(new boost::timer::auto_cpu_timer(3));
        }

        // The random number generator
        typedef std::mt19937 RNG;
        unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
        RNG rng(seed);

        // The optimiser
        int max_gen = 100;
        NSGAII<RNG> optimiser(rng, eval_server);
        MaxGenCheckpoint max_gen_terminate(max_gen);
    //    SavePopCheckpoint save_pop(1, working_dir);
        std::vector<double> ref_point = {1, -1};
        Hypervolume hvol(ref_point, working_dir, 1, Hypervolume::TERMINATION, 50);
    //    hvol.log();
        std::string mail_subj("Hypervolume of front from FON optimiser ");
    //    MailCheckpoint mail(10, hvol, mail_subj);
    //    std::string my_address("*****@*****.**");
    //    mail.addAddress(my_address);
        MetricLinePlot hvol_plot(hvol);
        PlotFrontVTK plotfront;
    //    ResetMutXvrDebugFlags reset_flags;
    //    SerialiseCheckpoint<NSGAII<RNG> > save_state(1, optimiser, working_dir);
        optimiser.add_checkpoint(max_gen_terminate);
    //    optimiser.add_checkpoint(save_state);
    //    optimiser.add_checkpoint(save_pop);
        optimiser.add_checkpoint(hvol);
        optimiser.add_checkpoint(hvol_plot);
        optimiser.add_checkpoint(plotfront);
    //    optimiser.add_checkpoint(mail);
    //    optimiser.add_checkpoint(reset_flags);
    //    optimiser.visualise();

        // Initialise population
        int pop_size = 1000;
        PopulationSPtr pop = intialisePopulationRandomDVAssignment(pop_size, test_problem.getProblemDefinitions(), rng);
        optimiser.getRealMutationOperator().setMutationInverseDVSize(pop->at(0));

        // Run the optimisation
        optimiser(pop);

        t.reset((boost::timer::auto_cpu_timer *) nullptr);
        if (ofs.is_open())
        {
            ofs << timer_info.str();
            ofs.close();
        }
        std::cout << timer_info.str() << std::endl;
        
    }
    else
    {


        // create evaluator client
        ParallelEvaluatePopClientNonBlocking eval_client(env, world, test_problem.getProblemDefinitions(), test_problem);
        //logging eval_client
        std::string log_filename = "evaluation_timing_worker" + std::to_string(world.rank()) + ".log";
        std::ofstream eval_strm(log_filename.c_str());
        if (eval_strm.is_open())
        {
            eval_client.log(ParallelEvaluatorBase::LVL1, eval_strm);
        }
        eval_client();
    }

    return EXIT_SUCCESS;
    
}
Beispiel #11
0
/* accept the socket and do a little sanity checking */
static int dsi_tcp_open(DSI *dsi)
{
    pid_t pid;
    SOCKLEN_T len;

    len = sizeof(dsi->client);
    dsi->socket = accept(dsi->serversock, (struct sockaddr *) &dsi->client, &len);

#ifdef TCPWRAP
    {
        struct request_info req;
        request_init(&req, RQ_DAEMON, dsi->program, RQ_FILE, dsi->socket, NULL);
        fromhost(&req);
        if (!hosts_access(&req)) {
            LOG(deny_severity, logtype_dsi, "refused connect from %s", eval_client(&req));
            close(dsi->socket);
            errno = ECONNREFUSED;
            dsi->socket = -1;
        }
    }
#endif /* TCPWRAP */

    if (dsi->socket < 0)
        return -1;

    getitimer(ITIMER_PROF, &itimer);
    if (0 == (pid = fork()) ) { /* child */
        static struct itimerval timer = {{0, 0}, {DSI_TCPTIMEOUT, 0}};
        struct sigaction newact, oldact;
        u_int8_t block[DSI_BLOCKSIZ];
        size_t stored;

        /* Immediateyl mark globally that we're a child now */
        parent_or_child = 1;

        /* reset signals */
        server_reset_signal();

#ifndef DEBUGGING
        /* install an alarm to deal with non-responsive connections */
        newact.sa_handler = timeout_handler;
        sigemptyset(&newact.sa_mask);
        newact.sa_flags = 0;
        sigemptyset(&oldact.sa_mask);
        oldact.sa_flags = 0;
        setitimer(ITIMER_PROF, &itimer, NULL);

        if ((sigaction(SIGALRM, &newact, &oldact) < 0) ||
            (setitimer(ITIMER_REAL, &timer, NULL) < 0)) {
            LOG(log_error, logtype_dsi, "dsi_tcp_open: %s", strerror(errno));
            exit(EXITERR_SYS);
        }
#endif

        /* read in commands. this is similar to dsi_receive except
         * for the fact that we do some sanity checking to prevent
         * delinquent connections from causing mischief. */

        /* read in the first two bytes */
        len = dsi_stream_read(dsi, block, 2);
        if (!len ) {
            /* connection already closed, don't log it (normal OSX 10.3 behaviour) */
            exit(EXITERR_CLNT);
        }
        if (len < 2 || (block[0] > DSIFL_MAX) || (block[1] > DSIFUNC_MAX)) {
            LOG(log_error, logtype_dsi, "dsi_tcp_open: invalid header");
            exit(EXITERR_CLNT);
        }

        /* read in the rest of the header */
        stored = 2;
        while (stored < DSI_BLOCKSIZ) {
            len = dsi_stream_read(dsi, block + stored, sizeof(block) - stored);
            if (len > 0)
                stored += len;
            else {
                LOG(log_error, logtype_dsi, "dsi_tcp_open: stream_read: %s", strerror(errno));
                exit(EXITERR_CLNT);
            }
        }

        dsi->header.dsi_flags = block[0];
        dsi->header.dsi_command = block[1];
        memcpy(&dsi->header.dsi_requestID, block + 2,
               sizeof(dsi->header.dsi_requestID));
        memcpy(&dsi->header.dsi_code, block + 4, sizeof(dsi->header.dsi_code));
        memcpy(&dsi->header.dsi_len, block + 8, sizeof(dsi->header.dsi_len));
        memcpy(&dsi->header.dsi_reserved, block + 12,
               sizeof(dsi->header.dsi_reserved));
        dsi->clientID = ntohs(dsi->header.dsi_requestID);

        /* make sure we don't over-write our buffers. */
        dsi->cmdlen = min(ntohl(dsi->header.dsi_len), DSI_CMDSIZ);

        stored = 0;
        while (stored < dsi->cmdlen) {
            len = dsi_stream_read(dsi, dsi->commands + stored, dsi->cmdlen - stored);
            if (len > 0)
                stored += len;
            else {
                LOG(log_error, logtype_dsi, "dsi_tcp_open: stream_read: %s", strerror(errno));
                exit(EXITERR_CLNT);
            }
        }

        /* stop timer and restore signal handler */
#ifndef DEBUGGING
        memset(&timer, 0, sizeof(timer));
        setitimer(ITIMER_REAL, &timer, NULL);
        sigaction(SIGALRM, &oldact, NULL);
#endif

        LOG(log_info, logtype_dsi, "AFP/TCP session from %s:%u",
            getip_string((struct sockaddr *)&dsi->client),
            getip_port((struct sockaddr *)&dsi->client));
    }

    /* send back our pid */
    return pid;
}
Beispiel #12
0
int main( int argc, char *argv[] )
{
    char *fn = "main()";
    char f_randfile[ PATH_MAX ];
    int listensd;                      /* socket descriptor we'll bind to */
    int clientsd;                      /* incoming socket descriptor */
    int addrlen;
    struct sockaddr_in srvaddr;
    struct sockaddr_in cliaddr;
    pthread_t ThreadId;                /* thread id of each incoming conn */
    pthread_t RecycleThread;           /* used just for the recycle thread */
    pthread_attr_t attr;               /* generic thread attribute struct */
    int rc, i, fd;
    unsigned int ui;
    pid_t pid;                         /* used just for a fork call */
    struct linger lingerstruct;        /* for the socket reuse stuff */
    int flag;                          /* for the socket reuse stuff */
    ICC_Struct *ICC_tptr;
    extern char *optarg;
    extern int optind;
    char ConfigFile[ MAXPATHLEN ];     /* path to our config file */
#ifdef HAVE_LIBWRAP
    struct request_info r;             /* request struct for libwrap */
#endif

    flag = 1;
    ConfigFile[0] = '\0';

    /*
     * Ignore signals we don't want to die from but we don't care enough
     * about to catch.
     */
    signal( SIGPIPE, SIG_IGN );
    signal( SIGHUP, SIG_IGN );


    while (( i = getopt( argc, argv, "f:h" ) ) != EOF )
    {
        switch( i )
        {
        case 'f':
            /* user specified a config filename */
            strncpy( ConfigFile, optarg, sizeof ConfigFile -1 );
            ConfigFile[ sizeof ConfigFile - 1 ] = '\0';
            syslog( LOG_INFO, "%s: Using configuration file '%s'",
                    fn, ConfigFile );
            break;

        case 'h':
            Usage();
            exit( 0 );

        case '?':
            Usage();
            exit( 1 );
        }
    }


    /*
     * Make sure we know which config file to use and then set our config
     * options.
     */
    if ( ! ConfigFile[0] )
    {
        strncpy( ConfigFile, DEFAULT_CONFIG_FILE, sizeof ConfigFile -1 );
        ConfigFile[ sizeof ConfigFile - 1 ] = '\0';
        syslog( LOG_INFO, "%s: Using default configuration file '%s'.",
                fn, ConfigFile );
    }

    SetConfigOptions( ConfigFile );
    SetLogOptions();

    /*
     * Just for logging purposes, are we doing SELECT caching or not?
     */
    if ( PC_Struct.enable_select_cache )
        syslog( LOG_INFO, "%s: SELECT caching is enabled", fn );
    else
        syslog( LOG_INFO, "%s: SELECT caching is disabled", fn );

#ifdef HAVE_LIBWRAP
    /*
     * Set our tcpd service name
     */
    if (service = strrchr(argv[0], '/'))
        service++;
    else
        service = argv[0];
#endif

    /*
     * Initialize some stuff.
     */
    rc = pthread_mutex_init(&mp, NULL);
    if ( rc )
    {
        syslog(LOG_ERR, "%s: pthread_mutex_init() returned error [%d] initializing main mutex.  Exiting.", fn, rc );
        exit( 1 );
    }

    rc = pthread_mutex_init(&trace, NULL);
    if ( rc )
    {
        syslog(LOG_ERR, "%s: pthread_mutex_init() returned error [%d] initializing trace mutex.  Exiting.", fn, rc );
        exit( 1 );
    }

    TraceUser[0] = '\0';

    syslog( LOG_INFO, "%s: Allocating %d IMAP connection structures.",
            fn, PC_Struct.cache_size );

    ICC_free = (ICC_Struct *)malloc( ( sizeof ( ICC_Struct ) )
                                     * PC_Struct.cache_size );

    if ( ! ICC_free )
    {
        syslog(LOG_ERR, "%s: malloc() failed to allocate [%d] IMAPConnectionContext structures: %s", fn, PC_Struct.cache_size, strerror( errno ) );
        exit( 1 );
    }

    memset( ICC_free, 0, sizeof ( ICC_Struct ) * PC_Struct.cache_size );

    ICC_tptr = ICC_free;

    /*
     * Bug fixed by Gary Mills <*****@*****.**>.  I was pre-incrementing
     * ICC_tptr and then assigning.  I guess gcc evaluates the expression
     * incorrectly, since I never had a problem with this.  Gary had the
     * problem with cc, so it's fixed here.
     */
    for ( ui = 0; ui < PC_Struct.cache_size - 1; ui++ )
    {
        ICC_tptr->next = ICC_tptr + 1;
        ICC_tptr++;
    }

    memset( ICC_HashTable, 0, sizeof ICC_HashTable );

    ServerInit();

    /* detach from our parent if necessary */
    if (! (getppid() == 1) && ( ! PC_Struct.foreground_mode ) )
    {
        syslog( LOG_INFO, "%s: Configured to run in background mode.", fn );

        if ( (pid = fork()) < 0)
        {
            syslog(LOG_ERR, "%s: initial call to fork() failed: %s", fn, strerror(errno));
            exit( 1 );
        }
        else if ( pid > 0)
        {
            exit( 0 );
        }

        if (setsid() == -1)
        {
            syslog(LOG_WARNING, "%s: setsid() failed: %s",
                   fn, strerror(errno));
        }
        if ( (pid = fork()) < 0)
        {
            syslog(LOG_ERR, "%s: secondary call to fork() failed: %s", fn,
                   strerror(errno));
            exit( 1 );
        }
        else if ( pid > 0)
        {
            exit( 0 );
        }
    }
    else
    {
        syslog( LOG_INFO, "%s: Configured to run in foreground mode.", fn );
    }


    SetBannerAndCapability();

    if ( PC_Struct.login_disabled || PC_Struct.force_tls )
    {
        syslog( LOG_INFO, "%s: Enabling STARTTLS.", fn );
#if HAVE_LIBSSL
        if ( PC_Struct.support_starttls )
        {
            /* Initialize SSL_CTX */
            SSL_library_init();

            /* Need to seed PRNG, too! */
            if ( RAND_egd( ( RAND_file_name( f_randfile, sizeof( f_randfile ) ) == f_randfile ) ? f_randfile : "/.rnd" ) )
            {
                /* Not an EGD, so read and write it. */
                if ( RAND_load_file( f_randfile, -1 ) )
                    RAND_write_file( f_randfile );
            }

            SSL_load_error_strings();
            tls_ctx = SSL_CTX_new( TLSv1_client_method() );
            if ( tls_ctx == NULL )
            {
                syslog(LOG_ERR, "%s: Failed to create new SSL_CTX.  Exiting.", fn);
                exit( 1 );
            }

            /* Work around all known bugs */
            SSL_CTX_set_options( tls_ctx, SSL_OP_ALL );

            if ( ! SSL_CTX_load_verify_locations( tls_ctx,
                                                  PC_Struct.tls_ca_file,
                                                  PC_Struct.tls_ca_path ) ||
                    ! SSL_CTX_set_default_verify_paths( tls_ctx ) )
            {
                syslog(LOG_ERR, "%s: Failed to load CA data.  Exiting.", fn);
                exit( 1 );
            }

            if ( ! set_cert_stuff( tls_ctx,
                                   PC_Struct.tls_cert_file,
                                   PC_Struct.tls_key_file ) )
            {
                syslog(LOG_ERR, "%s: Failed to load cert/key data.  Exiting.", fn);
                exit( 1 );
            }

            SSL_CTX_set_verify(tls_ctx, SSL_VERIFY_NONE, verify_callback);
        }
        else
#endif /* HAVE_LIBSSL */
        {
            /* We're screwed!  We won't be able to login without SASL */
            syslog(LOG_ERR, "%s: IMAP server has LOGINDISABLED and we can't do STARTTLS.  Exiting.", fn);
            exit( 1 );
        }
    }

    memset( (char *) &srvaddr, 0, sizeof srvaddr );
    srvaddr.sin_family = PF_INET;
    if ( !PC_Struct.listen_addr )
    {
        srvaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    }
    else
    {
        srvaddr.sin_addr.s_addr = inet_addr( PC_Struct.listen_addr );
        if ( srvaddr.sin_addr.s_addr  == -1 )
        {
            syslog( LOG_ERR, "%s: bad bind address: '%s' specified in config file.  Exiting.", fn, PC_Struct.listen_addr );
            exit( 1 );
        }
    }


    syslog(LOG_INFO, "%s: Binding to tcp %s:%d", fn, PC_Struct.listen_addr ?
           PC_Struct.listen_addr : "*", PC_Struct.listen_port );
    srvaddr.sin_port = htons(PC_Struct.listen_port);

    listensd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if ( listensd == -1 )
    {
        syslog(LOG_ERR, "%s: socket() failed: %s", fn, strerror(errno));
        exit( 1 );
    }

    setsockopt(listensd, SOL_SOCKET, SO_REUSEADDR, (void *)&flag,
               sizeof(flag));
    lingerstruct.l_onoff = 1;
    lingerstruct.l_linger = 5;
    setsockopt(listensd, SOL_SOCKET, SO_LINGER, (void *)&lingerstruct,
               sizeof(lingerstruct));

    if ( PC_Struct.send_tcp_keepalives )
    {
        lingerstruct.l_onoff = 1;
        syslog( LOG_INFO, "%s: Enabling SO_KEEPALIVE.", fn );
        setsockopt( listensd, SOL_SOCKET, SO_KEEPALIVE, (void *)&lingerstruct.l_onoff, sizeof lingerstruct.l_onoff );
    }


    if ( bind(listensd, (struct sockaddr *)&srvaddr, sizeof( srvaddr ) ) < 0 )
    {
        syslog(LOG_ERR, "%s: bind() failed: %s", fn, strerror(errno) );
        exit( 1 );
    }

    /*
     * Create and mmap() our stat file while we're still root.  Since it's
     * configurable, we want to make sure we do this as root so there's the
     * greatest possibility that we'll have permission to write where we
     * need to.
     */
    syslog( LOG_INFO, "%s: Using global statistics file '%s'", fn,
            PC_Struct.stat_filename );

    fd = open( PC_Struct.stat_filename, O_RDWR | O_CREAT, S_IREAD | S_IWRITE );
    if ( fd == -1 )
    {
        syslog(LOG_ERR, "%s: open() failed for '%s': %s -- Exiting.", fn,
               PC_Struct.stat_filename, strerror( errno ) );
        exit( 1 );
    }

    if ( ( ftruncate( fd, sizeof( IMAPCounter_Struct ) ) ) == -1 )
    {
        syslog(LOG_ERR, "%s: ftruncate() failed: %s -- Exiting.",
               fn, strerror( errno ) );
        exit( 1 );
    }

    IMAPCount = ( IMAPCounter_Struct *)mmap( 0, sizeof( IMAPCounter_Struct ),
                PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );

    if ( IMAPCount == MAP_FAILED )
    {
        syslog(LOG_ERR, "%s: mmap() failed: %s -- Exiting.",
               fn, strerror( errno ) );
        exit( 1 );
    }

    memset( IMAPCount, 0, sizeof( IMAPCounter_Struct ) );
    IMAPCount->StartTime = time( 0 );
    IMAPCount->CountTime = time( 0 );

    if ( BecomeNonRoot() )
        exit( 1 );

    /* some misc thread setup */
    rc = pthread_attr_init( &attr );
    if ( rc )
    {
        syslog(LOG_ERR, "%s: pthread_attr_init() failed: [%d]\n", fn, rc);
        exit( 1 );
    }

    rc = pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
    if ( rc )
    {
        syslog(LOG_ERR, "%s: pthread_attr_setdetachstate() failed: [%d]\n",
               fn, rc);
        exit( 1 );
    }

    /* launch a recycle thread before we loop */
    pthread_create( &RecycleThread, &attr, (void *)ICC_Recycle_Loop, NULL );

    syslog(LOG_INFO, "%s: Launched ICC recycle thread with id %d",
           fn, RecycleThread );

    /*
     * Now start listening and accepting connections.
     */
    if ( listen(listensd, MAX_CONN_BACKLOG) < 0)
    {
        syslog( LOG_ERR, "%s: listen() failed: %s -- Exiting",
                fn, strerror(errno));
        exit( 1 );
    }

    syslog( LOG_INFO, "%s: Normal server startup.", fn );

    /*
     * Main server loop
     */
    for ( ;; )
    {
        /*
         * Bug fixed by Gary Mills <*****@*****.**>.  I forgot
         * to initialize addrlen.
         */
        addrlen = sizeof cliaddr;
        clientsd = accept( listensd, (struct sockaddr *)&cliaddr, &addrlen );
        if ( clientsd == -1 )
        {
            syslog(LOG_WARNING, "%s: accept() failed: %s -- retrying",
                   fn, strerror(errno));
            sleep( 1 );
            continue;
        }

#ifdef HAVE_LIBWRAP
        request_init(&r, RQ_DAEMON, service, 0);
        request_set(&r, RQ_FILE, clientsd, 0);
        sock_host(&r);
        if (!hosts_access(&r))
        {
            shutdown(clientsd, SHUT_RDWR);
            close(clientsd);
            syslog(deny_severity, "refused connection from %s", eval_client(&r));
            continue;
        }
#endif

        IMAPCount->TotalClientConnectionsAccepted++;
        IMAPCount->CurrentClientConnections++;

        if ( IMAPCount->CurrentClientConnections >
                IMAPCount->PeakClientConnections )
            IMAPCount->PeakClientConnections = IMAPCount->CurrentClientConnections;

        pthread_create( &ThreadId, &attr, (void *)HandleRequest, (void *)clientsd );

    }
}
Beispiel #13
0
void
answer_first()
{
	struct sockaddr		sockstruct;
	int			newsock;
	socklen_t		socklen;
	int			flags;
	struct request_info	ri;
	struct spawn *sp;

	/* Answer the call to hunt: */
	socklen = sizeof sockstruct;
	newsock = accept(Socket, (struct sockaddr *) &sockstruct, &socklen);
	if (newsock < 0) {
		logit(LOG_ERR, "accept");
		return;
	}

	/* Check for access permissions: */
	request_init(&ri, RQ_DAEMON, "huntd", RQ_FILE, newsock, 0);
	fromhost(&ri);
	if (hosts_access(&ri) == 0) {
		logx(LOG_INFO, "rejected connection from %s", eval_client(&ri));
		close(newsock);
		return;
	}

	/* Remember this spawning connection: */
	sp = (struct spawn *)malloc(sizeof *sp);
	if (sp == NULL) {
		logit(LOG_ERR, "malloc");
		close(newsock);
		return;
	}
	memset(sp, '\0', sizeof *sp);

	/* Keep the calling machine's source addr for ident purposes: */
	memcpy(&sp->source, &sockstruct, sizeof sp->source);
	sp->sourcelen = socklen;

	/* Warn if we lose connection info: */
	if (socklen > sizeof Spawn->source) 
		logx(LOG_WARNING, 
		    "struct sockaddr is not big enough! (%d > %zu)",
		    socklen, sizeof Spawn->source);

	/*
	 * Turn off blocking I/O, so a slow or dead terminal won't stop
	 * the game.  All subsequent reads check how many bytes they read.
	 */
	flags = fcntl(newsock, F_GETFL, 0);
	flags |= O_NDELAY;
	(void) fcntl(newsock, F_SETFL, flags);

	/* Start listening to the spawning connection */
	sp->fd = newsock;
	FD_SET(sp->fd, &Fds_mask);
	if (sp->fd >= Num_fds)
		Num_fds = sp->fd + 1;

	sp->reading_msg = 0;
	sp->inlen = 0;

	/* Add to the spawning list */
	if ((sp->next = Spawn) != NULL)
		Spawn->prevnext = &sp->next;
	sp->prevnext = &Spawn;
	Spawn = sp;
}
Beispiel #14
0
int main( int argc, char *argv[] )
{
    const char *fn = "main()";
    char f_randfile[ PATH_MAX ];
    int listensd;                      /* socket descriptor we'll bind to */
    int clientsd;                      /* incoming socket descriptor */
    int sockaddrlen;                       
    struct sockaddr_storage srvaddr;
    struct sockaddr_storage cliaddr;
    pthread_t ThreadId;                /* thread id of each incoming conn */
    pthread_t RecycleThread;           /* used just for the recycle thread */
    pthread_attr_t attr;               /* generic thread attribute struct */
    int rc, i, fd;
    unsigned int ui;
    struct linger lingerstruct;        /* for the socket reuse stuff */
    int flag;                          /* for the socket reuse stuff */
    ICC_Struct *ICC_tptr;             
    extern char *optarg;
    extern int optind;
    char ConfigFile[ MAXPATHLEN ];     /* path to our config file */
    char PidFile[ MAXPATHLEN ];		/* path to our pidfile */
#ifdef HAVE_LIBWRAP
    struct request_info r;             /* request struct for libwrap */
#endif
    struct addrinfo aihints, *ai;
    int gaierrnum;

    flag = 1;
    ConfigFile[0] = '\0';
    strncpy( PidFile, DEFAULT_PID_FILE, sizeof PidFile -1 );

    /*
     * Ignore signals we don't want to die from but we don't care enough
     * about to catch.
     */
    signal( SIGPIPE, SIG_IGN );
    signal( SIGHUP, SIG_IGN );
    

    while (( i = getopt( argc, argv, "f:p:h" ) ) != EOF )
    {
	switch( i )
	{
	case 'f':
	    /* user specified a config filename */
	    strncpy( ConfigFile, optarg, sizeof ConfigFile -1 );
	    ConfigFile[ sizeof ConfigFile - 1 ] = '\0';
	    syslog( LOG_INFO, "%s: Using configuration file '%s'",
		    fn, ConfigFile );
	    break;
        
        case 'p':
            /* user specified a pidfile */
            strncpy( PidFile, optarg, sizeof PidFile -1 );
            PidFile[ sizeof PidFile - 1 ] = '\0';
            syslog( LOG_INFO, "%s: Using pidfile '%s'",
            fn, PidFile );
            break;
        
	case 'h':
	    Usage();
	    exit( 0 );

	case '?':
	    Usage();
	    exit( 1 );
	}
    }


    /* 
     * Make sure we know which config file to use and then set our config
     * options.
     */
    if ( ! ConfigFile[0] )
    {
	strncpy( ConfigFile, DEFAULT_CONFIG_FILE, sizeof ConfigFile -1 );
	ConfigFile[ sizeof ConfigFile - 1 ] = '\0';
	syslog( LOG_INFO, "%s: Using default configuration file '%s'.",
		fn, ConfigFile );
    }

    SetDefaultConfigValues(&PC_Struct);
    SetConfigOptions( ConfigFile );
    SetLogOptions();

    /*
     * Just for logging purposes, are we doing SELECT caching or not?
     */
    if ( PC_Struct.enable_select_cache )
	syslog( LOG_INFO, "%s: SELECT caching is enabled", fn );
    else
	syslog( LOG_INFO, "%s: SELECT caching is disabled", fn );
	
    /*
     * Just for logging purposes, are the admin commands enabled or not?
     */
     if ( PC_Struct.enable_admin_commands )
	 syslog( LOG_INFO, "%s: Internal admin commands are enabled", fn );
     else
	 syslog( LOG_INFO, "%s: Internal admin commands are disabled", fn );
     

#ifdef HAVE_LIBWRAP
    /*
     * Set our tcpd service name
     */
    if (service = strrchr(argv[0], '/'))
	    service++;
    else
	    service = argv[0];
#endif

    /*
     * Initialize some stuff.
     */
    rc = pthread_mutex_init(&mp, NULL);
    if ( rc )
    {
	syslog(LOG_ERR, "%s: pthread_mutex_init() returned error [%d] initializing main mutex.  Exiting.", fn, rc );
	exit( 1 );
    }

    rc = pthread_mutex_init(&trace, NULL);
    if ( rc )
    {
	syslog(LOG_ERR, "%s: pthread_mutex_init() returned error [%d] initializing trace mutex.  Exiting.", fn, rc );
	exit( 1 );
    }

    TraceUser[0] = '\0';
    
    syslog( LOG_INFO, "%s: Allocating %d IMAP connection structures.", 
	    fn, PC_Struct.cache_size );

    ICC_free = (ICC_Struct *)malloc( ( sizeof ( ICC_Struct ) ) 
		       * PC_Struct.cache_size );
    
    if ( ! ICC_free )
    {
	syslog(LOG_ERR, "%s: malloc() failed to allocate [%d] IMAPConnectionContext structures: %s", fn, PC_Struct.cache_size, strerror( errno ) );
	exit( 1 );
    }
    
    memset( ICC_free, 0, sizeof ( ICC_Struct ) * PC_Struct.cache_size );
    
    ICC_tptr = ICC_free;

    /*
     * Bug fixed by Gary Mills <*****@*****.**>.  I was pre-incrementing
     * ICC_tptr and then assigning.  I guess gcc evaluates the expression
     * incorrectly, since I never had a problem with this.  Gary had the
     * problem with cc, so it's fixed here.
     */
    for ( ui = 0; ui < PC_Struct.cache_size - 1; ui++ )
    {
	ICC_tptr->next = ICC_tptr + 1;
	ICC_tptr++;
    }
    
    memset( ICC_HashTable, 0, sizeof ICC_HashTable );


#if HAVE_LIBSSL
    /* Initialize SSL_CTX */
    syslog( LOG_INFO, "%s: Enabling openssl library.", fn );
    SSL_library_init();

    /* Set up OpenSSL thread protection */
    ssl_thread_setup(fn);

    /* Need to seed PRNG, too! */
    if ( RAND_egd( ( RAND_file_name( f_randfile, sizeof( f_randfile ) ) == f_randfile ) ? f_randfile : "/.rnd" ) )
    {
	/* Not an EGD, so read and write it. */
	if ( RAND_load_file( f_randfile, -1 ) )
	RAND_write_file( f_randfile );
    }

    SSL_load_error_strings();
    tls_ctx = SSL_CTX_new( TLSv1_client_method() );
    if ( tls_ctx == NULL )
    { 
	syslog(LOG_ERR, "%s: Failed to create new SSL_CTX.  Exiting.", fn);
	exit( 1 );
    }
 
    /* Work around all known bugs */
    SSL_CTX_set_options( tls_ctx, SSL_OP_ALL );
 
    if ( PC_Struct.tls_ca_file != NULL || PC_Struct.tls_ca_path != NULL )
    {
	rc = SSL_CTX_load_verify_locations( tls_ctx,
					    PC_Struct.tls_ca_file,
					    PC_Struct.tls_ca_path );
    }
    else
    {
	rc = SSL_CTX_set_default_verify_paths( tls_ctx );
    }
    if ( rc == 0 )
    { 
	syslog(LOG_ERR, "%s: Failed to load CA data.  Exiting.", fn);
	exit( 1 );
    }
 
    if ( ! set_cert_stuff( tls_ctx,
			    PC_Struct.tls_cert_file,
			    PC_Struct.tls_key_file ) )
    { 
	syslog(LOG_ERR, "%s: Failed to load cert/key data.  Exiting.", fn);
	exit( 1 );
    }

    SSL_CTX_set_verify(tls_ctx, SSL_VERIFY_NONE, verify_callback);
#endif /* HAVE_LIBSSL */


    ServerInit();
    
    /* Daemonize() would go here */

    SetBannerAndCapability();
    

    /*
     * We don't need to check PC_Struct.support_starttls since we
     * probably have refetched the capability list after a STARTTLS
     * if we did one; it won't ever be supported at this point.
     *
     * It also makes no difference to check PC_Struct.force_tls now
     * because we've either done a STARTTLS or we haven't - all that
     * matters is if we got LOGINDISABLED or not.
     *
     * Note that all these things *ARE* tested when checking the
     * server capabilities (in fact, the following check is probably
     * a duplicate).
     */
    if ( PC_Struct.login_disabled )
    {
	/* We're screwed!  We can't login */
	syslog(LOG_ERR,
		"%s: IMAP server has LOGINDISABLED.  Exiting.",
		fn);
	exit( 1 );
    }


    memset( &aihints, 0, sizeof aihints );
    aihints.ai_family = AF_UNSPEC;
    aihints.ai_socktype = SOCK_STREAM;
    aihints.ai_flags = AI_PASSIVE;

    if ( ( gaierrnum = getaddrinfo( PC_Struct.listen_addr,
				    PC_Struct.listen_port,
				    &aihints, &ai ) ) )
	{
	    syslog( LOG_ERR, "%s: bad bind address: '%s' specified in config file.  Exiting.", fn, PC_Struct.listen_addr );
	    exit( 1 );
	}

    syslog( LOG_INFO, "%s: Binding to tcp %s:%s", fn,
	    PC_Struct.listen_addr ? PC_Struct.listen_addr : "*",
	    PC_Struct.listen_port );

    for ( ; ai != NULL; ai = ai->ai_next )
    {
	listensd = socket( ai->ai_family, ai->ai_socktype, ai->ai_protocol );
    if ( listensd == -1 )
    {
	    syslog(LOG_WARNING, "%s: socket() failed: %s", fn, strerror(errno));
	    continue;
    }

    setsockopt(listensd, SOL_SOCKET, SO_REUSEADDR, (void *)&flag, 
	       sizeof(flag));
    lingerstruct.l_onoff = 1;
    lingerstruct.l_linger = 5;
    setsockopt(listensd, SOL_SOCKET, SO_LINGER, (void *)&lingerstruct, 
	       sizeof(lingerstruct));

    if ( PC_Struct.send_tcp_keepalives )
    {
	lingerstruct.l_onoff = 1;
	syslog( LOG_INFO, "%s: Enabling SO_KEEPALIVE.", fn );
	setsockopt( listensd, SOL_SOCKET, SO_KEEPALIVE, (void *)&lingerstruct.l_onoff, sizeof lingerstruct.l_onoff );
    }

	memcpy( &srvaddr, ai->ai_addr, ai->ai_addrlen );
	if ( bind( listensd, (struct sockaddr *)&srvaddr, ai->ai_addrlen ) < 0 )
    {
	    syslog(LOG_WARNING, "%s: bind() failed: %s", fn, strerror(errno) );
	    continue;
	}
	else break;
    }
    if ( ai == NULL )
    {
	syslog( LOG_ERR, "%s: no useable addresses to bind to", fn );
	exit( EXIT_FAILURE);
    }

    /*
     * Create and mmap() our stat file while we're still root.  Since it's
     * configurable, we want to make sure we do this as root so there's the
     * greatest possibility that we'll have permission to write where we
     * need to.
     */
    syslog( LOG_INFO, "%s: Using global statistics file '%s'", fn,
	    PC_Struct.stat_filename );
    
    fd = open( PC_Struct.stat_filename, O_RDWR | O_CREAT, S_IREAD | S_IWRITE );
    if ( fd == -1 )
    {
	syslog(LOG_ERR, "%s: open() failed for '%s': %s -- Exiting.", fn, 
	       PC_Struct.stat_filename, strerror( errno ) );
	exit( 1 );
    }
    
    if ( ( ftruncate( fd, sizeof( IMAPCounter_Struct ) ) ) == -1 )
    {
	syslog(LOG_ERR, "%s: ftruncate() failed: %s -- Exiting.", 
	       fn, strerror( errno ) );
	exit( 1 );
    }
    
    IMAPCount = ( IMAPCounter_Struct *)mmap( 0, sizeof( IMAPCounter_Struct ), 
		    PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
    
    if ( IMAPCount == MAP_FAILED )
    {
	syslog(LOG_ERR, "%s: mmap() failed: %s -- Exiting.", 
	       fn, strerror( errno ) );
	exit( 1 );
    }
    
    memset( IMAPCount, 0, sizeof( IMAPCounter_Struct ) );
    IMAPCount->StartTime = time( 0 );
    IMAPCount->CountTime = time( 0 );

    /*
     * Daemonize as late as possible, so that connection failures can be caught
     * and startup aborted before dettaching from parent
     */
    Daemonize( PidFile );

    if ( BecomeNonRoot() )
	exit( 1 );

    /* some misc thread setup */
    rc = pthread_attr_init( &attr );
    if ( rc )
    {
	syslog(LOG_ERR, "%s: pthread_attr_init() failed: [%d]\n", fn, rc);
	exit( 1 );
    }
    
    rc = pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
    if ( rc )
    {
	syslog(LOG_ERR, "%s: pthread_attr_setdetachstate() failed: [%d]\n", 
	       fn, rc);
	exit( 1 );
    }

    /* launch a recycle thread before we loop */
    pthread_create( &RecycleThread, &attr, (void *)ICC_Recycle_Loop, NULL );

    syslog(LOG_INFO, "%s: Launched ICC recycle thread with id %d", 
	   fn, (int)RecycleThread );

    /*
     * Now start listening and accepting connections.
     */
    if ( listen(listensd, MAX_CONN_BACKLOG) < 0)
    {
	syslog( LOG_ERR, "%s: listen() failed: %s -- Exiting", 
	       fn, strerror(errno));
	exit( 1 );
    }

    syslog( LOG_INFO, "%s: squirrelmail-imap_proxy version %s normal server startup.", fn, IMAP_PROXY_VERSION );

    /*
     * Main server loop
     */
    for ( ;; )
    {
	/*
	 * Bug fixed by Gary Mills <*****@*****.**>.  I forgot
	 * to initialize sockaddrlen.
	 */
	sockaddrlen = sizeof cliaddr;
	clientsd = accept( listensd, (struct sockaddr *)&cliaddr,
			   &sockaddrlen );
	if ( clientsd == -1 )
	{
	    syslog(LOG_WARNING, "%s: accept() failed: %s -- retrying", 
		   fn, strerror(errno));
	    sleep( 1 );
	    continue;
	}

#ifdef HAVE_LIBWRAP
	request_init(&r, RQ_DAEMON, service, 0);
	request_set(&r, RQ_FILE, clientsd, 0);
	sock_host(&r);
	if (!hosts_access(&r))
	{
	    shutdown(clientsd, SHUT_RDWR);
	    close(clientsd);
	    syslog(deny_severity, "refused connection from %s", eval_client(&r));
	    continue;
	}
#endif

	IMAPCount->TotalClientConnectionsAccepted++;
	IMAPCount->CurrentClientConnections++;
	
	if ( IMAPCount->CurrentClientConnections > 
	     IMAPCount->PeakClientConnections )
	    IMAPCount->PeakClientConnections = IMAPCount->CurrentClientConnections;
	
	rc = pthread_create( &ThreadId, &attr, (void *)HandleRequest, (void *)clientsd );
	if (rc != 0) {
	    syslog(LOG_ERR, "%s: pthread_create() returned error [%d] for HandleRequest.", fn, rc );
	    close(clientsd);
	}
	
    }
}
Beispiel #15
0
static void accept_connection(int sock, void *unused) {
	int new_sd;
	pid_t pid;
	struct sockaddr addr;
	struct sockaddr_in *nptr;
	socklen_t addrlen;
	int rc;
#ifdef HAVE_LIBWRAP
	struct request_info req;
#endif

	/* DO NOT REMOVE! 01/29/2007 single process daemon will fail if this is removed */
	if (mode == SINGLE_PROCESS_DAEMON)
		register_read_handler(sock, accept_connection, NULL);

	/* wait for a connection request */
	while (1) {

		/* we got a live one... */
		if ((new_sd = accept(sock, 0, 0)) >= 0)
			break;

		/* handle the error */
		else {

			/* bail out if necessary */
			if (sigrestart == TRUE || sigshutdown == TRUE)
				return;

			/* try and handle temporary errors */
			if (errno == EWOULDBLOCK || errno == EINTR || errno == ECHILD) {
				if (mode == MULTI_PROCESS_DAEMON)
					sleep(1);
				else
					return;
			} else
				break;
		}
	}

	/* hey, there was an error... */
	if (new_sd < 0) {

		/* log error to syslog facility */
		syslog(LOG_ERR, "Network server accept failure (%d: %s)", errno, strerror(errno));

		/* close socket prior to exiting */
		close(sock);
		if (mode == MULTI_PROCESS_DAEMON)
			do_exit(STATE_CRITICAL);
		return;
	}

#ifdef HAVE_LIBWRAP

	/* Check whether or not connections are allowed from this host */
	request_init(&req, RQ_DAEMON, "nsca", RQ_FILE, new_sd, 0);
	fromhost(&req);

	if (!hosts_access(&req)) {
		/* refuse the connection */
		syslog(LOG_ERR, "refused connect from %s", eval_client(&req));
		close(new_sd);
		return;
	}
#endif


	/* fork() if we have to... */
	if (mode == MULTI_PROCESS_DAEMON) {

		pid = fork();
		if (pid) {
			/* parent doesn't need the new connection */
			close(new_sd);
			return;
		} else {
			/* child does not need to listen for connections */
			close(sock);
		}
	}

	/* find out who just connected... */
	addrlen = sizeof(addr);
	rc = getpeername(new_sd, &addr, &addrlen);

	if (rc < 0) {
		/* log error to syslog facility */
		syslog(LOG_ERR, "Error: Network server getpeername() failure (%d: %s)", errno, strerror(errno));

		/* close socket prior to exiting */
		close(new_sd);
		if (mode == MULTI_PROCESS_DAEMON)
			do_exit(STATE_CRITICAL);
		return;
	}

	nptr = (struct sockaddr_in *)&addr;

	/* log info to syslog facility */
	if (debug == TRUE)
		syslog(LOG_DEBUG, "Connection from %s port %d", inet_ntoa(nptr->sin_addr), nptr->sin_port);

	/* handle the connection */
	if (mode == SINGLE_PROCESS_DAEMON)
		/* mark the connection as ready to be handled */
		register_write_handler(new_sd, handle_connection, NULL);
	else
		/* handle the client connection */
		handle_connection(new_sd, NULL);

	return;
}
Beispiel #16
0
void ssh_channel_ftcp_incoming_connection(SshIpError error, SshStream stream,
                                          void *context)
{
  SshRemoteTcpForward fwd = (SshRemoteTcpForward)context;
  char ip[20], port[20];
  SshBuffer buffer;

  SSH_DEBUG(5, ("connection to forwarded TCP/IP port"));
  
  /* We should only receive new connection notifications. */
  if (error != SSH_IP_NEW_CONNECTION)
    ssh_fatal("ssh_channel_ftcp_incoming_connection: error %d", (int)error);

  /* Get remote ip address and port. */
  if (!ssh_tcp_get_remote_address(stream, ip, sizeof(ip)))
    strcpy(ip, "UNKNOWN");
  if (!ssh_tcp_get_remote_port(stream, port, sizeof(port)))
    strcpy(port, "UNKNOWN");

  SSH_TRACE(0, ("Connection to forwarded port %s from %s:%s",
                fwd->port, ip, port));
  ssh_log_event(fwd->common->config->log_facility,
                SSH_LOG_INFORMATIONAL,
                "Connection to forwarded port %s from %s:%s",
                fwd->port, fwd->common->remote_host, port);

  /* XXXXXXXX */
#ifdef HAVE_LIBWRAP
  {
    struct request_info req;
    struct servent *serv;
    char fwdportname[32];
    void *old_handler;
    
    old_handler = signal(SIGCHLD, SIG_DFL);

    /* try to find port's name in /etc/services */
    serv = getservbyport(atoi(fwd->port), "tcp");
    if (serv == NULL)
      {
        /* not found (or faulty getservbyport) -
           use the number as a name */
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%s", fwd->port);
      }
    else
      {
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%.20s",
                 serv->s_name);
      }
    /* fill req struct with port name and fd number */
    request_init(&req, RQ_DAEMON, fwdportname,
                 RQ_FILE, ssh_stream_fd_get_readfd(stream), NULL);
    fromhost(&req);
    if (!hosts_access(&req))
      {
        ssh_conn_send_debug(fwd->common->conn, TRUE,
                            "Fwd connection from %.500s to local port " \
                            "%s refused by tcp_wrappers.",
                            eval_client(&req), fwdportname);
        ssh_stream_destroy(stream);
        signal(SIGCHLD, old_handler);
    
        return;
      }
    signal(SIGCHLD, old_handler);
        
    ssh_log_event(fwd->common->config->log_facility, SSH_LOG_INFORMATIONAL,
                  "Remote fwd connect from %.500s to local port %s",
                  eval_client(&req), fwdportname);
  }
#endif /* HAVE_LIBWRAP */

  /* Register that we have an open channel. */
  ssh_common_new_channel(fwd->common);
  
  /* Send a request to open a channel and connect it to the given port. */
  ssh_buffer_init(&buffer);
  ssh_encode_buffer(&buffer,
                    SSH_FORMAT_UINT32_STR,
                    fwd->address_to_bind, strlen(fwd->address_to_bind),
                    SSH_FORMAT_UINT32, (SshUInt32) atol(fwd->port),
                    SSH_FORMAT_UINT32_STR, ip, strlen(ip),
                    SSH_FORMAT_UINT32, (SshUInt32) atol(port),
                    SSH_FORMAT_END);
  ssh_conn_send_channel_open(fwd->common->conn, "forwarded-tcpip",
                             stream, TRUE, FALSE, SSH_TCPIP_WINDOW,
                             SSH_TCPIP_PACKET_SIZE,
                             ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer),
                             NULL,
                             ssh_channel_tcp_connection_destroy,
                             (void *)fwd->common, NULL, NULL);
  ssh_buffer_uninit(&buffer);
}  
Beispiel #17
0
void ssh_channel_dtcp_incoming_connection(SshStreamNotification op,
                                          SshStream stream, void *context)
{
  SshLocalTcpForward fwd = (SshLocalTcpForward)context;
  char ip[20], port[20];

  /* We should only receive new connection notifications. */
  if (op != SSH_IP_NEW_CONNECTION)
    ssh_fatal("ssh_channel_dtcp_incoming_connection: op %d", (int)op);

  /* Get remote ip address and port. */
  if (!ssh_tcp_get_remote_address(stream, ip, sizeof(ip)))
    strcpy(ip, "UNKNOWN");
  if (!ssh_tcp_get_remote_port(stream, port, sizeof(port)))
    strcpy(port, "UNKNOWN");

#ifdef HAVE_LIBWRAP
  {
    struct request_info req;
    struct servent *serv;
    char fwdportname[32];
    void *old_handler;
    
    old_handler = signal(SIGCHLD, SIG_DFL);
    
    /* try to find port's name in /etc/services */
    serv = getservbyport(atoi(fwd->port), "tcp");
    if (serv == NULL)
      {
        /* not found (or faulty getservbyport) -
           use the number as a name */
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%s", fwd->port);
      }
    else
      {
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%.20s",
                 serv->s_name);
      }
    /* fill req struct with port name and fd number */
    request_init(&req, RQ_DAEMON, fwdportname,
                 RQ_FILE, ssh_stream_fd_get_readfd(stream), NULL);
    fromhost(&req);
    if (!hosts_access(&req))
      {
        ssh_conn_send_debug(fwd->common->conn, TRUE,
                            "Fwd connection from %.500s to local port %s "
                            "refused by tcp_wrappers.",
                            eval_client(&req), fwdportname);
        ssh_log_event(fwd->common->config->log_facility, SSH_LOG_WARNING,
                      "Fwd connection from %.500s to local port %s "
                      "refused by tcp_wrappers.",
                      eval_client(&req), fwdportname);
        ssh_stream_destroy(stream);
        signal(SIGCHLD, old_handler);

        return;
      }
    signal(SIGCHLD, old_handler);

    ssh_log_event(fwd->common->config->log_facility, SSH_LOG_INFORMATIONAL,
                  "direct fwd connect from %.500s to local port %s",
                  eval_client(&req), fwdportname);
  }
#endif /* HAVE_LIBWRAP */

  /* Send a request to open a channel and connect it to the given port. */
  ssh_channel_dtcp_open_to_remote(fwd->common, stream,
                                  fwd->connect_to_host,
                                  fwd->connect_to_port,
                                  ip, port);
}
int main(int argc, char * argv[]) {
    boost::mpi::environment env(argc, argv);
    boost::mpi::communicator world;

    MetronamicaOF2Parameters params;
    int err = processOptions(argc, argv, params);
    if (err != 0)
    {
        return EXIT_SUCCESS;
    }

//    std::vector<double> real_lowerbounds  = {500,   -1000,   0.05,   500,   -1000,   0.05,   500,   -1000,   0.05,   500,   -1000,   0.05,   500,   -1000,   0.05,   500,   -1000,   0.05,   500,   -1000,   0.05,   500,   -1000,   0.05,   500,   -1000,   0.05,   500,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   -100,   -1000,   0.05,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0 };
//    std::vector<double> real_upperbounds =  {5000,   1000,   5,   5000,   1000,   5,   5000,   1000,   5,   5000,   1000,   5,   5000,   1000,   5,   5000,   1000,   5,   5000,   1000,   5,   5000,   1000,   5,   5000,   1000,   5,   5000,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   100,   1000,   5,   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1   };
//    int num_classes = 16;
    params.evaluator_id = world.rank();
    MetronamicaCalibrationObjectiveFunction metro_eval(params);

    
    
    if (world.rank() == 0)
    {
//        std::ofstream ofs(time_fname.c_str());
//        if (ofs.is_open())
//        {
//            t.reset(new boost::timer::auto_cpu_timer(timer_info, 3));
//        }
//        else
//        {
//            std::cerr << "Error: Could not open file for writing time elapsed for search, using std::cout";
//            t.reset(new boost::timer::auto_cpu_timer(3));
//        }


        //create evaluator server
        boost::filesystem::path eval_log = params.save_dir.second / "evaluation_timing.log";
        std::ofstream eval_strm(eval_log.c_str());
        ParallelEvaluatePopServerNonBlocking eval_server(env, world, metro_eval.getProblemDefinitions());
        if (eval_strm.is_open())
        {
            eval_server.log(ParallelEvaluatorBase::LVL1, eval_strm);
        }

        // The random number generator
        typedef std::mt19937 RNG;
        if (params.search_rand_seed == -1) params.search_rand_seed = std::chrono::system_clock::now().time_since_epoch().count();
        RNG rng(params.search_rand_seed);


        // The optimiser
        NSGAII<RNG> optimiser(rng, eval_server);
        if (eval_strm.is_open())
        {
            optimiser.log(eval_strm, eval_log, NSGAII<RNG>::LVL1 );
        }
        std::vector<double> ref_point =  {-0.1, 1, -0.1};
        std::vector<double> unitise_point = {1,0, 1};
        createCheckpoints(optimiser, params, ref_point, unitise_point);

        // Initialise population

        PopulationSPtr pop(new Population);
        if (params.pop_file_xml.first != "none")
        {
            pop = restore_population(params.pop_file_xml.second);
        }
        else if (params.pop_file_txt.first != "none")
        {
            pop.reset(new Population(params.pop_file_txt.second, metro_eval.getProblemDefinitions()));
        }
        else
        {
            pop = intialisePopulationRandomDVAssignment(params.pop_size, metro_eval.getProblemDefinitions(), rng);
        }
        optimiser.getRealMutationOperator().setMutationInverseDVSize(pop->at(0));


//        hvol(pop);
//        std::cout << "Hypervolume: " << hvol.getVal() << std::endl;

        // Run the optimisation
        optimiser(pop);

        postProcessResults(metro_eval, pop, params);

    }
    else
    {
        std::string log_file_name = "worker_" + std::to_string(world.rank()) + "_timing.log";
        boost::filesystem::path eval_log = params.save_dir.second / log_file_name;
        std::ofstream eval_strm(eval_log.c_str());
        ParallelEvaluatePopClientNonBlocking eval_client(env, world, metro_eval.getProblemDefinitions(), metro_eval);
        if (eval_strm.is_open())
        {
            eval_client.log(ParallelEvaluatorBase::LVL1, eval_strm);
        }

        //logging eval_client
//        std::string log_filename = "evaluation_timing_worker" + std::to_string(world.rank()) + ".log";
//        boost::filesystem::path eval_log = working_dir.second / log_filename;
//        std::ofstream eval_strm(eval_log.c_str());
//        if (eval_strm.is_open())
//        {
//            eval_client.log(ParallelEvaluatorBase::LVL1, eval_strm);
//        }
        eval_client();
    }
}
Beispiel #19
0
/*
 * Handle a UDP packet sent to the well known port.
 */
static void
handle_wkport(int fd)
{
	struct sockaddr		fromaddr;
	socklen_t		fromlen;
	u_int16_t		query;
	u_int16_t		response;
	struct request_info	ri;

	request_init(&ri, RQ_DAEMON, "huntd", RQ_FILE, fd, 0);
	fromhost(&ri);
	fromlen = sizeof fromaddr;
	if (recvfrom(fd, &query, sizeof query, 0, &fromaddr, &fromlen) == -1)
	{
		logit(LOG_WARNING, "recvfrom");
		return;
	}

#ifdef DEBUG
	fprintf(stderr, "query %d (%s) from %s:%d\n", query,
		query == C_MESSAGE ? "C_MESSAGE" :
		query == C_SCORES ? "C_SCORES" :
		query == C_PLAYER ? "C_PLAYER" :
		query == C_MONITOR ? "C_MONITOR" : "?",
		inet_ntoa(((struct sockaddr_in *)&fromaddr)->sin_addr),
		ntohs(((struct sockaddr_in *)&fromaddr)->sin_port));
#endif

	/* Do we allow access? */
	if (hosts_access(&ri) == 0) {
		logx(LOG_INFO, "rejected connection from %s", eval_client(&ri));
		return;
	}

	query = ntohs(query);

	switch (query) {
	  case C_MESSAGE:
		if (Nplayer <= 0)
			/* Don't bother replying if nobody to talk to: */
			return;
		/* Return the number of people playing: */
		response = Nplayer;
		break;
	  case C_SCORES:
		/* Someone wants the statistics port: */
		response = stat_port;
		break;
	  case C_PLAYER:
	  case C_MONITOR:
		/* Someone wants to play or watch: */
		if (query == C_MONITOR && Nplayer <= 0)
			/* Don't bother replying if there's nothing to watch: */
			return;
		/* Otherwise, tell them how to get to the game: */
		response = sock_port;
		break;
	  default:
		logit(LOG_INFO, "unknown udp query %d", query);
		return;
	}

	response = ntohs(response);
	if (sendto(fd, &response, sizeof response, 0,
	    &fromaddr, sizeof fromaddr) == -1)
		logit(LOG_WARNING, "sendto");
}
Beispiel #20
0
int main(int ac, char **av)
{
    extern char *optarg;
    extern int optind;
    int opt, sock_in, sock_out, newsock, i, pid = 0, on = 1;
    socklen_t aux;
    int remote_major, remote_minor;
    int perm_denied = 0;
    int ret;
    fd_set fdset;
#ifdef HAVE_IPV6_SMTH
    struct sockaddr_in6 sin;
#else
    struct sockaddr_in sin;
#endif
    char buf[100];              /* Must not be larger than remote_version. */
    char remote_version[100];   /* Must be at least as big as buf. */
    char addr[STRLEN];
    char *comment;
    char *ssh_remote_version_string = NULL;
    FILE *f;

#if defined(SO_LINGER) && defined(ENABLE_SO_LINGER)
    struct linger linger;
#endif                          /* SO_LINGER */
    int done;

    chdir(BBSHOME);
    /* Save argv[0]. */
    saved_argv = av;
    if (strchr(av[0], '/'))
        av0 = strrchr(av[0], '/') + 1;
    else
        av0 = av[0];

    /* Prevent core dumps to avoid revealing sensitive information. */
    signals_prevent_core();

    /* Set SIGPIPE to be ignored. */
    signal(SIGPIPE, SIG_IGN);

    /* Initialize configuration options to their default values. */
    initialize_server_options(&options);
    addr[0]=0;

    /* Parse command-line arguments. */
    while ((opt = getopt(ac, av, "f:a:p:b:k:h:g:diqV:")) != EOF) {
        switch (opt) {
        case 'f':
            config_file_name = optarg;
            break;
        case 'd':
            debug_flag = 1;
            break;
        case 'i':
            inetd_flag = 1;
            break;
        case 'q':
            options.quiet_mode = 1;
            break;
        case 'b':
            options.server_key_bits = atoi(optarg);
            break;
        case 'a':
            if(optarg[0])
                snprintf(addr,STRLEN,"%s",optarg);
            break;
        case 'p':
            if(isdigit(optarg[0]))
                options.port=atoi(optarg);
            break;
        case 'g':
            options.login_grace_time = atoi(optarg);
            break;
        case 'k':
            options.key_regeneration_time = atoi(optarg);
            break;
        case 'h':
            options.host_key_file = optarg;
            break;
        case 'V':
            ssh_remote_version_string = optarg;
            break;
        case '?':
        default:
#ifdef F_SECURE_COMMERCIAL

#endif                          /* F_SECURE_COMMERCIAL */
            fprintf(stderr, "sshd version %s [%s]\n", SSH_VERSION, HOSTTYPE);
            fprintf(stderr, "Usage: %s [options]\n", av0);
            fprintf(stderr, "Options:\n");
            fprintf(stderr, "  -f file    Configuration file (default %s/sshd_config)\n", ETCDIR);
            fprintf(stderr, "  -d         Debugging mode\n");
            fprintf(stderr, "  -i         Started from inetd\n");
            fprintf(stderr, "  -q         Quiet (no logging)\n");
            fprintf(stderr, "  -a addr    Bind to the specified address (default: all)\n");
            fprintf(stderr, "  -p port    Listen on the specified port (default: 22)\n");
            fprintf(stderr, "  -k seconds Regenerate server key every this many seconds (default: 3600)\n");
            fprintf(stderr, "  -g seconds Grace period for authentication (default: 300)\n");
            fprintf(stderr, "  -b bits    Size of server RSA key (default: 768 bits)\n");
            fprintf(stderr, "  -h file    File from which to read host key (default: %s)\n", HOST_KEY_FILE);
            fprintf(stderr, "  -V str     Remote version string already read from the socket\n");
            exit(1);
        }
    }

    /* Read server configuration options from the configuration file. */
    read_server_config(&options, config_file_name);

    /* Fill in default values for those options not explicitly set. */
    fill_default_server_options(&options);

    /* Check certain values for sanity. */
    if (options.server_key_bits < 512 || options.server_key_bits > 32768) {
        fprintf(stderr, "fatal: Bad server key size.\n");
        exit(1);
    }
    if (options.port < 1 || options.port > 65535) {
        fprintf(stderr, "fatal: Bad port number.\n");
        exit(1);
    }
    if (options.umask != -1) {
        umask(options.umask);
    }

    /* Check that there are no remaining arguments. */
    if (optind < ac) {
        fprintf(stderr, "fatal: Extra argument %.100s.\n", av[optind]);
        exit(1);
    }

    /* Initialize the log (it is reinitialized below in case we forked). */
    log_init(av0, debug_flag && !inetd_flag, debug_flag || options.fascist_logging, options.quiet_mode, options.log_facility);

    debug("sshd version %.100s [%.100s]", SSH_VERSION, HOSTTYPE);

    /* Load the host key.  It must have empty passphrase. */
    done = load_private_key(geteuid(), options.host_key_file, "", &sensitive_data.host_key, &comment);

    if (!done) {
        if (debug_flag) {
            fprintf(stderr, "Could not load host key: %.200s\n", options.host_key_file);
            fprintf(stderr, "fatal: Please check that you have sufficient permissions and the file exists.\n");
        } else {
            log_init(av0, !inetd_flag, 1, 0, options.log_facility);
            error("fatal: Could not load host key: %.200s.  Check path and permissions.", options.host_key_file);
        }
        exit(1);
    }
    xfree(comment);

    /* If not in debugging mode, and not started from inetd, disconnect from
       the controlling terminal, and fork.  The original process exits. */
    if (!debug_flag && !inetd_flag)
#ifdef HAVE_DAEMON
        if (daemon(0, 0) < 0)
            error("daemon: %.100s", strerror(errno));
    chdir(BBSHOME);
#else                           /* HAVE_DAEMON */
    {
#ifdef TIOCNOTTY
        int fd;
#endif                          /* TIOCNOTTY */

        /* Fork, and have the parent exit.  The child becomes the server. */
        if (fork())
            exit(0);

        /* Redirect stdin, stdout, and stderr to /dev/null. */
        freopen("/dev/null", "r", stdin);
        freopen("/dev/null", "w", stdout);
        freopen("/dev/null", "w", stderr);

        /* Disconnect from the controlling tty. */
#ifdef TIOCNOTTY
        fd = open("/dev/tty", O_RDWR | O_NOCTTY);
        if (fd >= 0) {
            (void) ioctl(fd, TIOCNOTTY, NULL);
            close(fd);
        }
#endif                          /* TIOCNOTTY */
#ifdef HAVE_SETSID
#ifdef ultrix
        setpgrp(0, 0);
#else                           /* ultrix */
        if (setsid() < 0)
            error("setsid: %.100s", strerror(errno));
#endif
#endif                          /* HAVE_SETSID */
    }
#endif                          /* HAVE_DAEMON */

    /* Reinitialize the log (because of the fork above). */
    log_init(av0, debug_flag && !inetd_flag, debug_flag || options.fascist_logging, options.quiet_mode, options.log_facility);

    /* Check that server and host key lengths differ sufficiently.  This is
       necessary to make double encryption work with rsaref.  Oh, I hate
       software patents. */
    if (options.server_key_bits > sensitive_data.host_key.bits - SSH_KEY_BITS_RESERVED && options.server_key_bits < sensitive_data.host_key.bits + SSH_KEY_BITS_RESERVED) {
        options.server_key_bits = sensitive_data.host_key.bits + SSH_KEY_BITS_RESERVED;
        debug("Forcing server key to %d bits to make it differ from host key.", options.server_key_bits);
    }

    /* Initialize memory allocation so that any freed MP_INT data will be
       zeroed. */
    rsa_set_mp_memory_allocation();

    /* Do not display messages to stdout in RSA code. */
    rsa_set_verbose(debug_flag);

    /* Initialize the random number generator. */
    debug("Initializing random number generator; seed file %.200s", options.random_seed_file);
    random_initialize(&sensitive_data.random_state, geteuid(), options.random_seed_file);

    /* Chdir to the root directory so that the current disk can be unmounted
       if desired. */

    idle_timeout = options.idle_timeout;

    /* Start listening for a socket, unless started from inetd. */
    if (inetd_flag) {
        int s1, s2;

        s1 = dup(0);            /* Make sure descriptors 0, 1, and 2 are in use. */
        s2 = dup(s1);
        sock_in = dup(0);
        sock_out = dup(1);
        /* We intentionally do not close the descriptors 0, 1, and 2 as our
           code for setting the descriptors won\'t work if ttyfd happens to
           be one of those. */
        debug("inetd sockets after dupping: %d, %d", sock_in, sock_out);

        /* Generate an rsa key. */
        log_msg("Generating %d bit RSA key.", options.server_key_bits);
        rsa_generate_key(&sensitive_data.private_key, &public_key, &sensitive_data.random_state, options.server_key_bits);
        random_save(&sensitive_data.random_state, geteuid(), options.random_seed_file);
        log_msg("RSA key generation complete.");
    } else {
        /* Create socket for listening. */
#ifdef HAVE_IPV6_SMTH
        listen_sock = socket(AF_INET6, SOCK_STREAM, 0);
#else       
        listen_sock = socket(AF_INET, SOCK_STREAM, 0);
#endif
        if (listen_sock < 0)
            fatal("socket: %.100s", strerror(errno));

        /* Set socket options.  We try to make the port reusable and have it
           close as fast as possible without waiting in unnecessary wait states
           on close. */
        setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on));
#if defined(SO_LINGER) && defined(ENABLE_SO_LINGER)
        linger.l_onoff = 1;
        linger.l_linger = 15;
        setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger));
#endif                          /* SO_LINGER */

        /* Initialize the socket address. */
        memset(&sin, 0, sizeof(sin));
#ifdef HAVE_IPV6_SMTH
        sin.sin6_family = AF_INET6;
        if ( inet_pton(AF_INET6, addr, &(sin.sin6_addr)) <= 0 )
            sin.sin6_addr = in6addr_any;
        sin.sin6_port = htons(options.port);
#else
        sin.sin_family = AF_INET;
        if ( inet_pton(AF_INET, addr, &(sin.sin_addr)) <= 0 )
            sin.sin_addr.s_addr = htonl(INADDR_ANY);
        sin.sin_port = htons(options.port);
#endif
        /* Bind the socket to the desired port. */
        if (bind(listen_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
            error("bind: %.100s", strerror(errno));
            shutdown(listen_sock, 2);
            close(listen_sock);
            fatal("Bind to port %d failed: %.200s.", options.port, strerror(errno));
        }
        /* COMMAN : setuid to bbs */

        if(setgid(BBSGID)==-1)
            exit(8);
        if(setuid(BBSUID)==-1)
            exit(8);

#if 0 /* etnlegend, 2006.10.31 ... */
        if (!debug_flag) {
            /* Record our pid in /etc/sshd_pid to make it easier to kill the
               correct sshd.  We don\'t want to do this before the bind above
               because the bind will fail if there already is a daemon, and this
               will overwrite any old pid in the file. */
            f = fopen(options.pid_file, "w");
            if (f) {
                fprintf(f, "%u\n", (unsigned int) getpid());
                fclose(f);
            }
        }
#endif

        /* Start listening on the port. */
        log_msg("Server listening on port %d.", options.port);
        if (listen(listen_sock, 5) < 0)
            fatal("listen: %.100s", strerror(errno));

        /* Generate an rsa key. */
        log_msg("Generating %d bit RSA key.", options.server_key_bits);
        rsa_generate_key(&sensitive_data.private_key, &public_key, &sensitive_data.random_state, options.server_key_bits);
        random_save(&sensitive_data.random_state, geteuid(), options.random_seed_file);
        log_msg("RSA key generation complete.");

        /* Schedule server key regeneration alarm. */
        signal(SIGALRM, key_regeneration_alarm);
        alarm(options.key_regeneration_time);

        /* Arrange to restart on SIGHUP.  The handler needs listen_sock. */
        signal(SIGHUP, sighup_handler);
        signal(SIGTERM, sigterm_handler);
        signal(SIGQUIT, sigterm_handler);

        /* AIX sends SIGDANGER when memory runs low.  The default action is
           to terminate the process.  This sometimes makes it difficult to
           log in and fix the problem. */

#ifdef SIGDANGER
        signal(SIGDANGER, sigdanger_handler);
#endif                          /* SIGDANGER */

        /* Arrange SIGCHLD to be caught. */
        signal(SIGCHLD, main_sigchld_handler);


        if(!debug_flag){
            if(!addr[0])
                sprintf(buf,"var/sshbbsd.%d.pid",options.port);
            else
                sprintf(buf,"var/sshbbsd.%d_%s.pid",options.port,addr);
            if((f=fopen(buf,"w"))){
                fprintf(f,"%d\n",(int)getpid());
                fclose(f);
            }
        }

        /* Stay listening for connections until the system crashes or the
           daemon is killed with a signal. */
        for (;;) {
            if (received_sighup)
                sighup_restart();

            /* Wait in select until there is a connection. */
            FD_ZERO(&fdset);
            FD_SET(listen_sock, &fdset);
            ret = select(listen_sock + 1, &fdset, NULL, NULL, NULL);
            if (ret < 0 || !FD_ISSET(listen_sock, &fdset)) {
                if (errno == EINTR)
                    continue;
                error("select: %.100s", strerror(errno));
                continue;
            }

            aux = sizeof(sin);
            newsock = accept(listen_sock, (struct sockaddr *) &sin, &aux);
            if (newsock < 0) {
                if (errno == EINTR)
                    continue;
                error("accept: %.100s", strerror(errno));
                continue;
            }

            /* Got connection.  Fork a child to handle it, unless we are in
               debugging mode. */
            if (debug_flag) {
                /* In debugging mode.  Close the listening socket, and start
                   processing the connection without forking. */
                debug("Server will not fork when running in debugging mode.");
                close(listen_sock);
                sock_in = newsock;
                sock_out = newsock;
                pid = getpid();
#ifdef LIBWRAP
                {
                    struct request_info req;

                    signal(SIGCHLD, SIG_DFL);

                    request_init(&req, RQ_DAEMON, av0, RQ_FILE, newsock, NULL);
                    fromhost(&req);
                    if (!hosts_access(&req))
                        refuse(&req);
                    syslog(allow_severity, "connect from %s", eval_client(&req));
                }
#endif                          /* LIBWRAP */
                break;
            } else {
#ifdef CHECK_IP_LINK
#ifdef HAVE_IPV6_SMTH
                if (check_IP_lists(sin.sin6_addr)==0)
#else
                if (check_IP_lists(sin.sin_addr.s_addr)==0) 
#endif
#endif
                /* Normal production daemon.  Fork, and have the child process
                   the connection.  The parent continues listening. */
                if ((pid = fork()) == 0) {
                    /* Child.  Close the listening socket, and start using
                       the accepted socket.  Reinitialize logging (since our
                       pid has changed).  We break out of the loop to handle
                       the connection. */
                    close(listen_sock);
                    sock_in = newsock;
                    sock_out = newsock;
#ifdef LIBWRAP
                    {
                        struct request_info req;

                        signal(SIGCHLD, SIG_DFL);

                        request_init(&req, RQ_DAEMON, av0, RQ_FILE, newsock, NULL);
                        fromhost(&req);
                        if (!hosts_access(&req))
                            refuse(&req);
                        syslog(allow_severity, "connect from %s", eval_client(&req));
                    }
#endif                          /* LIBWRAP */

                    log_init(av0, debug_flag && !inetd_flag, options.fascist_logging || debug_flag, options.quiet_mode, options.log_facility);
                    break;
                }
            }

            /* Parent.  Stay in the loop. */
            if (pid < 0)
                error("fork: %.100s", strerror(errno));
            else
                debug("Forked child %d.", pid);

            /* Mark that the key has been used (it was "given" to the child). */
            key_used = 1;

            random_acquire_light_environmental_noise(&sensitive_data.random_state);

            /* Close the new socket (the child is now taking care of it). */
            close(newsock);
        }
    }

    /* This is the child processing a new connection. */

    /* Disable the key regeneration alarm.  We will not regenerate the key
       since we are no longer in a position to give it to anyone.  We will
       not restart on SIGHUP since it no longer makes sense. */
    alarm(0);
    signal(SIGALRM, SIG_DFL);
    signal(SIGHUP, SIG_DFL);
    signal(SIGTERM, SIG_DFL);
    signal(SIGQUIT, SIG_DFL);
    signal(SIGCHLD, SIG_DFL);

    /* Set socket options for the connection.  We want the socket to close
       as fast as possible without waiting for anything.  If the connection
       is not a socket, these will do nothing. */
    /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */
#if defined(SO_LINGER) && defined(ENABLE_SO_LINGER)
    linger.l_onoff = 1;
    linger.l_linger = 15;
    setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger));
#endif                          /* SO_LINGER */

    /* Register our connection.  This turns encryption off because we do not
       have a key. */
    packet_set_connection(sock_in, sock_out, &sensitive_data.random_state);

    /* Log the connection. */
    log_msg("Connection from %.100s port %d", get_remote_ipaddr(), get_remote_port());

    /* Check whether logins are denied from this host. */
    {
        const char *hostname = get_canonical_hostname();
        const char *ipaddr = get_remote_ipaddr();
        int i;

        if (options.num_deny_hosts > 0) {
            for (i = 0; i < options.num_deny_hosts; i++)
                if (match_host(hostname, ipaddr, options.deny_hosts[i]))
                    perm_denied = 1;
        }
        if ((!perm_denied) && options.num_allow_hosts > 0) {
            for (i = 0; i < options.num_allow_hosts; i++)
                if (match_host(hostname, ipaddr, options.allow_hosts[i]))
                    break;
            if (i >= options.num_allow_hosts)
                perm_denied = 1;
        }
        if (perm_denied && options.silent_deny) {
            close(sock_in);
            close(sock_out);
            exit(0);
        }
    }

    /* We don't want to listen forever unless the other side successfully
       authenticates itself.  So we set up an alarm which is cleared after
       successful authentication.  A limit of zero indicates no limit.
       Note that we don't set the alarm in debugging mode; it is just annoying
       to have the server exit just when you are about to discover the bug. */
    signal(SIGALRM, grace_alarm_handler);
    if (!debug_flag)
        alarm(options.login_grace_time);


    if (ssh_remote_version_string == NULL) {
        /* Send our protocol version identification. */
        snprintf(buf, sizeof(buf), "SSH-%d.%d-%.50s", PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
        strcat(buf, "\n");
        if (write(sock_out, buf, strlen(buf)) != strlen(buf))
            fatal_severity(SYSLOG_SEVERITY_INFO, "Could not write ident string.");
    }

    if (ssh_remote_version_string == NULL) {
        /* Read other side\'s version identification. */
        for (i = 0; i < sizeof(buf) - 1; i++) {
            if (read(sock_in, &buf[i], 1) != 1)
                fatal_severity(SYSLOG_SEVERITY_INFO, "Did not receive ident string.");
            if (buf[i] == '\r') {
                buf[i] = '\n';
                buf[i + 1] = 0;
                break;
            }
            if (buf[i] == '\n') {
                /* buf[i] == '\n' */
                buf[i + 1] = 0;
                break;
            }
        }
        buf[sizeof(buf) - 1] = 0;
    } else {
        strncpy(buf, ssh_remote_version_string, sizeof(buf) - 1);
        buf[sizeof(buf) - 1] = 0;
    }

    /* Check that the versions match.  In future this might accept several
       versions and set appropriate flags to handle them. */
    if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, remote_version) != 3) {
        const char *s = "Protocol mismatch.\n";

        (void) write(sock_out, s, strlen(s));
        close(sock_in);
        close(sock_out);
        fatal_severity(SYSLOG_SEVERITY_INFO, "Bad protocol version identification: %.100s", buf);
    }
    debug("Client protocol version %d.%d; client software version %.100s", remote_major, remote_minor, remote_version);

    switch (check_emulation(remote_major, remote_minor, NULL, NULL)) {
    case EMULATE_MAJOR_VERSION_MISMATCH:
        {
            const char *s = "Protocol major versions differ.\n";

            (void) write(sock_out, s, strlen(s));
            close(sock_in);
            close(sock_out);
            fatal_severity(SYSLOG_SEVERITY_INFO, "Protocol major versions differ: %d vs. %d", PROTOCOL_MAJOR, remote_major);
        }
        break;
    case EMULATE_VERSION_TOO_OLD:
        packet_disconnect("Your ssh version is too old and is no " "longer supported.  Please install a newer version.");
        break;
    case EMULATE_VERSION_NEWER:
        packet_disconnect("This server does not support your " "new ssh version.");
        break;
    case EMULATE_VERSION_OK:
        break;
    default:
        fatal("Unexpected return value from check_emulation.");
    }

    if (perm_denied) {
        const char *hostname = get_canonical_hostname();

        log_msg("Connection from %.200s not allowed.\n", hostname);
        packet_disconnect("Sorry, you are not allowed to connect.");
     /*NOTREACHED*/}

    packet_set_nonblocking();

    /* Handle the connection.   We pass as argument whether the connection
       came from a privileged port. */
    do_connection(get_remote_port() < 1024);

    /* The connection has been terminated. */
    log_msg("Closing connection to %.100s", get_remote_ipaddr());
    packet_close();
    exit(0);
}