void test_SetsDefaultsWithoutEmptyConfigFile(void)
{
    config_t expected_config;
    SetDefaultConfigValues(&expected_config);

    config_t actual_config;
    Config_FromFile("test/support/empty", &actual_config);

    TEST_ASSERT_EQUAL_config_t(expected_config, actual_config);
}
void test_SetsDefaultsWithoutConfigFile(void)
{
    config_t expected_config;
    SetDefaultConfigValues(&expected_config);

    config_t actual_config;
    Config_FromFile(NULL, &actual_config);

    TEST_ASSERT_EQUAL_config_t(expected_config, actual_config);
}
void test_AnyConfigFileOptionsOverrideDefaults(void)
{
    config_t expected_config;
    SetDefaultConfigValues(&expected_config);
    expected_config.l2.hit_time_cycles = 10;

    config_t actual_config;
    Config_FromFile("test/support/l2_hit_time_10", &actual_config);

    TEST_ASSERT_EQUAL_config_t(expected_config, actual_config);
}
void test_ConfigDefaultValues(void)
{
    config_t expected_config;
    SetDefaultConfigValues(&expected_config);

    config_t default_config;
    ZERO_STRUCT(default_config);

    Config_Defaults(&default_config);

    TEST_ASSERT_EQUAL_config_t(expected_config, default_config);
}
Пример #5
0
void setUp(void)
{
    SetDefaultConfigValues(&config);

    main_mem = MainMem_Create(&(config.main_mem));
}
Пример #6
0
ConfigurationManager::ConfigurationManager()
{
   xercesc::XMLPlatformUtils::Initialize();

   SetDefaultConfigValues();
}
Пример #7
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);
	}
	
    }
}