Ejemplo n.º 1
0
void test_database_init()
{
  scheduler_t* scheduler;
  PGresult* db_result;
  GString* sql;

  scheduler = scheduler_init(testdb, NULL);
  database_init(scheduler);

  FO_ASSERT_PTR_NOT_NULL(scheduler->db_conn);

  sprintf(sqltmp, check_scheduler_tables, PQdb(scheduler->db_conn));
  sql = g_string_new(sqltmp);
  g_string_append(sql, "'users';");

  /* get the url for the fossology instance */
  db_result = database_exec(scheduler, sql->str);
  //printf("sql: %s\n", sql->str);
  // TODO skip this test since the order reported here is random, also it will crash if PQntuples < 5
  #if 0
  if(PQresultStatus(db_result) == PGRES_TUPLES_OK && PQntuples(db_result) != 0)
  {
    //printf("result: %s\n",  g_strdup(PQgetvalue(db_result, 0, 0)));
    FO_ASSERT_STRING_EQUAL(g_strdup(PQgetvalue(db_result, 0, 0)), "user_pk");
    FO_ASSERT_STRING_EQUAL(g_strdup(PQgetvalue(db_result, 1, 0)), "user_name");
    FO_ASSERT_STRING_EQUAL(g_strdup(PQgetvalue(db_result, 2, 0)), "root_folder_fk");
    FO_ASSERT_STRING_EQUAL(g_strdup(PQgetvalue(db_result, 3, 0)), "user_desc");
    FO_ASSERT_STRING_EQUAL(g_strdup(PQgetvalue(db_result, 4, 0)), "user_seed");
  }
  #endif
  PQclear(db_result);
  g_string_free(sql, TRUE);
  scheduler_destroy(scheduler);
}
Ejemplo n.º 2
0
void test_database_update_event()
{
  scheduler_t* scheduler;
  char sql[512];
  PGresult* db_result;

  scheduler = scheduler_init(testdb, NULL);

  FO_ASSERT_PTR_NULL(scheduler->db_conn);
  database_init(scheduler);
  FO_ASSERT_PTR_NOT_NULL(scheduler->db_conn);
  
  Prepare_Testing_Data(scheduler);

  database_update_event(scheduler, NULL);
  sprintf(sql, "SELECT * FROM job;");
  db_result = database_exec(scheduler, sql);
  //printf("result: %s", PQget(db_result, 0, "job_name"));
  if(PQresultStatus(db_result) == PGRES_TUPLES_OK && PQntuples(db_result) != 0)
  {
    FO_ASSERT_STRING_EQUAL(PQget(db_result, 0, "job_name"), "testing file");
    FO_ASSERT_EQUAL(atoi(PQget(db_result, 0, "job_user_fk")), 1);
  }  
  PQclear(db_result);

  database_reset_queue(scheduler); 

  scheduler_destroy(scheduler);
}
Ejemplo n.º 3
0
void
check_spinn_packet_con_teardown(void)
{
	scheduler_destroy(&s);
	buffer_destroy(&b);
	spinn_packet_pool_destroy(&pool);
	spinn_packet_con_destroy(&c);
}
Ejemplo n.º 4
0
/*
 * The servers main dispatch loop for incoming requests using SSL over TCP
 */
static DWORD server_dispatch( Remote * remote )
{
	LONG result     = ERROR_SUCCESS;
	Packet * packet = NULL;
	THREAD * cpt    = NULL;

	dprintf( "[DISPATCH] entering server_dispatch( 0x%08X )", remote );

	// Bring up the scheduler subsystem.
	result = scheduler_initialize( remote );
	if( result != ERROR_SUCCESS )
		return result;

	while( TRUE )
	{
		if( event_poll( serverThread->sigterm, 0 ) )
		{
			dprintf( "[DISPATCH] server dispatch thread signaled to terminate..." );
			break;
		}

		result = server_socket_poll( remote, 100 );
		if( result > 0 )
		{
			result = packet_receive( remote, &packet );
			if( result != ERROR_SUCCESS ) {
				dprintf( "[DISPATCH] packet_receive returned %d, exiting dispatcher...", result );		
				break;
			}

			cpt = thread_create( command_process_thread, remote, packet );
			if( cpt )
			{
				dprintf( "[DISPATCH] created command_process_thread 0x%08X, handle=0x%08X", cpt, cpt->handle );
				thread_run( cpt );
			}
		}
		else if( result < 0 )
		{
			dprintf( "[DISPATCH] server_socket_poll returned %d, exiting dispatcher...", result );
			break;
		}
	}

	dprintf( "[DISPATCH] calling scheduler_destroy..." );
	scheduler_destroy();

	dprintf( "[DISPATCH] calling command_join_threads..." );
	command_join_threads();

	dprintf( "[DISPATCH] leaving server_dispatch." );

	return result;
}
Ejemplo n.º 5
0
void test_scheduler_sig_handle()
{
  scheduler_t* scheduler;

  scheduler = scheduler_init(testdb, NULL);

  FO_ASSERT_PTR_NULL(scheduler->db_conn);
  database_init(scheduler);
  FO_ASSERT_PTR_NOT_NULL(scheduler->db_conn);

  scheduler_sig_handle(1);
  scheduler_signal(scheduler);

  scheduler_destroy(scheduler);
}
Ejemplo n.º 6
0
static ERL_NIF_TERM
nif_scheduler_destroy(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]){

    state_ptr state = (state_ptr) enif_priv_data(env);
    
    if(state->initilised == 0 ) 
    {
        return enif_make_tuple2(env, 
            enif_make_atom(env, "state_error"), 
            enif_make_atom(env, "scheduler_not_inited"));
    }
    scheduler_destroy(state->scheduler_state);
    state->initilised = 0;
    return enif_make_atom(env, "ok");
}
Ejemplo n.º 7
0
DWORD server_deinit_http_winhttp(Remote* remote)
{
	HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx;

	dprintf("[WINHTTP] Deinitialising ...");

	WinHttpCloseHandle(ctx->connection);
	WinHttpCloseHandle(ctx->internet);

	dprintf("[DISPATCH] calling scheduler_destroy...");
	scheduler_destroy();

	dprintf("[DISPATCH] calling command_join_threads...");
	command_join_threads();

	return TRUE;
}
/*!
 * @brief The servers main dispatch loop for incoming requests using SSL over TCP
 * @param remote Pointer to the remote endpoint for this server connection.
 * @returns Indication of success or failure.
 */
static BOOL server_dispatch_tcp(Remote * remote, THREAD* dispatchThread)
{
	BOOL running = TRUE;
	LONG result = ERROR_SUCCESS;
	Packet *packet = NULL;
	THREAD *cpt = NULL;
	dprintf("[DISPATCH] entering server_dispatch( 0x%08X )", remote);

	// Bring up the scheduler subsystem.
	result = scheduler_initialize(remote);
	if (result != ERROR_SUCCESS) {
		return result;
	}

	while (running) {
		if (event_poll(dispatchThread->sigterm, 0)) {
			dprintf("[DISPATCH] server dispatch thread signaled to terminate...");
			break;
		}
		result = server_socket_poll(remote, 500000);
		if (result > 0) {
			result = packet_receive_via_ssl(remote, &packet);
			if (result != ERROR_SUCCESS) {
				dprintf("[DISPATCH] packet_receive returned %d, exiting dispatcher...", result);
				break;
			}
			running = command_handle(remote, packet);
			dprintf("[DISPATCH] command_process result: %s", (running ? "continue" : "stop"));
		}

		else if (result < 0) {
			dprintf("[DISPATCH] server_socket_poll returned %d, exiting dispatcher...", result);
			break;
		}
	}

	dprintf("[DISPATCH] calling scheduler_destroy...")
	scheduler_destroy();

	dprintf("[DISPATCH] calling command_join_threads...")
	command_join_threads();

	dprintf("[DISPATCH] leaving server_dispatch.");
	return result;
}
Ejemplo n.º 9
0
void test_event_loop_take()
{
  event_t* retval;
  scheduler_t* scheduler;
  scheduler = scheduler_init(testdb, NULL);
  scheduler_foss_config(scheduler);
  event_loop_t* vl = event_loop_get();

  vl->occupied = 0;
  vl->terminated = 1;

  retval = event_loop_take(vl);
  FO_ASSERT_PTR_NULL(retval);
  FO_ASSERT_FALSE(vl->occupied);
  FO_ASSERT_TRUE(vl->terminated);

  scheduler_destroy(scheduler);
}
Ejemplo n.º 10
0
void test_event_init()
{
  scheduler_t* scheduler;
  scheduler = scheduler_init(testdb, NULL);
  scheduler_foss_config(scheduler);

  event_t* e;

  sample_args = &call_num;
  e = event_init(sample_event, sample_args, "sample", s_name, s_line);

  FO_ASSERT_PTR_EQUAL(   e->func,     sample_event);
  FO_ASSERT_PTR_EQUAL(   e->argument, sample_args);
  FO_ASSERT_STRING_EQUAL(e->name,     "sample");

  g_free(e);
  scheduler_destroy(scheduler);
}
Ejemplo n.º 11
0
void test_database_exec_event()
{
  scheduler_t* scheduler;
  GString* sql;

  scheduler = scheduler_init(testdb, NULL);

  FO_ASSERT_PTR_NULL(scheduler->db_conn);
  database_init(scheduler);
  FO_ASSERT_PTR_NOT_NULL(scheduler->db_conn);

  sprintf(sqltmp, check_scheduler_tables, PQdb(scheduler->db_conn));
  sql = g_string_new(sqltmp);
  g_string_append(sql, "'user';");
  
  database_exec_event(scheduler, sql->str);
  scheduler_destroy(scheduler);
}
Ejemplo n.º 12
0
void test_event_loop_put()
{
  scheduler_t* scheduler;
  scheduler = scheduler_init(testdb, NULL);
  scheduler_foss_config(scheduler);
  event_t* e;

  sample_args = &call_num;
  event_signal(sample_event, sample_args);

  e = g_async_queue_pop(event_loop_get()->queue);

  FO_ASSERT_PTR_EQUAL(   e->func,     sample_event);
  FO_ASSERT_PTR_EQUAL(   e->argument, sample_args);
  FO_ASSERT_STRING_EQUAL(e->name,     "sample_event");

  event_loop_put(event_loop_get(),e);
  scheduler_destroy(scheduler);
}
Ejemplo n.º 13
0
void test_scheduler_daemonize()
{
  scheduler_t* scheduler;
  int res = 0;

  scheduler = scheduler_init(testdb, NULL);

  FO_ASSERT_PTR_NULL(scheduler->db_conn);
  database_init(scheduler);
  FO_ASSERT_PTR_NOT_NULL(scheduler->db_conn);

  //res = scheduler_daemonize(scheduler);
  FO_ASSERT_EQUAL(res, 0);

  res = kill_scheduler(1);
  FO_ASSERT_EQUAL(res, -1);

  scheduler_destroy(scheduler);
}
Ejemplo n.º 14
0
void test_event_loop_terminate()
{
  int retval = 0;
  scheduler_t* scheduler;
  scheduler = scheduler_init(testdb, NULL);
  scheduler_foss_config(scheduler);
  event_loop_t* vl = event_loop_get();

  vl->occupied = 0;
  vl->terminated = 1;

  event_signal(terminate_event, NULL);
  retval = event_loop_enter(scheduler, NULL, NULL);
  FO_ASSERT_EQUAL(retval, 0x0);
  FO_ASSERT_FALSE(vl->occupied);
  FO_ASSERT_TRUE(vl->terminated);

  scheduler_destroy(scheduler);
}
Ejemplo n.º 15
0
void test_scheduler_clear_config()
{
  scheduler_t* scheduler;

  scheduler = scheduler_init(testdb, NULL);

  FO_ASSERT_PTR_NULL(scheduler->db_conn);
  database_init(scheduler);
  FO_ASSERT_PTR_NOT_NULL(scheduler->db_conn);

  scheduler_clear_config(scheduler);
  FO_ASSERT_PTR_NULL(scheduler->db_conn);
  FO_ASSERT_PTR_NULL(scheduler->host_queue);
  FO_ASSERT_PTR_NULL(scheduler->host_url);
  FO_ASSERT_PTR_NULL(scheduler->email_subject);
  FO_ASSERT_PTR_NULL(scheduler->sysconfig);
  
  scheduler_destroy(scheduler);
}
Ejemplo n.º 16
0
void test_database_job()
{
  scheduler_t* scheduler;
  job_t* job;
  arg_int* params;
  int jq_pk;
  job_t tmp_job;

  scheduler = scheduler_init(testdb, NULL);

  FO_ASSERT_PTR_NULL(scheduler->db_conn);
  database_init(scheduler);
  FO_ASSERT_PTR_NOT_NULL(scheduler->db_conn);

  jq_pk = Prepare_Testing_Data(scheduler);

  params = g_new0(arg_int, 1);
  params->second = jq_pk;
  params->first = g_tree_lookup(scheduler->job_list, &params->second);
  job = params->first;
  if(params->first == NULL)
  {
    tmp_job.id             = params->second;
    tmp_job.status         = JB_NOT_AVAILABLE;
    tmp_job.running_agents = NULL;
    tmp_job.message        = NULL;

    job = &tmp_job;
  }

  FO_ASSERT_STRING_EQUAL(job_status_strings[job->status], "JOB_NOT_AVAILABLE");

  printf("jq: %d\n", jq_pk);
  database_job_processed(jq_pk, 2);
  database_job_log(jq_pk, "test log");
  database_job_priority(scheduler, job, 1);

  g_free(params);
  scheduler_destroy(scheduler);  
}
Ejemplo n.º 17
0
void test_email_notify()
{
  scheduler_t* scheduler;
  job_t* job;
  int jq_pk;

  scheduler = scheduler_init(testdb, NULL);

  FO_ASSERT_PTR_NULL(scheduler->db_conn);
  database_init(scheduler);
  email_init(scheduler);
  FO_ASSERT_PTR_NOT_NULL(scheduler->db_conn);

  jq_pk = Prepare_Testing_Data(scheduler);
  job = job_init(scheduler->job_list, scheduler->job_queue, "ununpack", "localhost", -1, 0, 0, 0, 0, NULL);
  job->id = jq_pk;
 
  database_update_job(scheduler, job, JB_FAILED); 
  FO_ASSERT_STRING_EQUAL(job_status_strings[job->status], "JOB_CHECKEDOUT");

  scheduler_destroy(scheduler);
}
Ejemplo n.º 18
0
/*
 * The servers main dispatch loop for incoming requests using SSL over TCP
 */
static DWORD server_dispatch_http_wininet( Remote * remote )
{
	LONG result     = ERROR_SUCCESS;
	Packet * packet = NULL;
	THREAD * cpt    = NULL;
	URL_COMPONENTS bits;
	DWORD ecount = 0;
	DWORD delay = 0;
	char tmpHostName[512];
	char tmpUrlPath[1024];

	if (global_expiration_timeout > 0) 
		remote->expiration_time  = current_unix_timestamp() + global_expiration_timeout;
	else
		remote->expiration_time = 0;
	
	remote->comm_timeout     = global_comm_timeout;
	remote->start_time       = current_unix_timestamp();
	remote->comm_last_packet = current_unix_timestamp();
	
	// Allocate the top-level handle
	if (!strcmp(global_meterpreter_proxy,"METERPRETER_PROXY")) {
		remote->hInternet = InternetOpen(global_meterpreter_ua, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	}
	else {
		remote->hInternet = InternetOpen(global_meterpreter_ua, INTERNET_OPEN_TYPE_PROXY, global_meterpreter_proxy, NULL, 0);
	}	if (!remote->hInternet) {
		dprintf("[DISPATCH] Failed InternetOpen: %d", GetLastError());
		return 0;
	}
	dprintf("[DISPATCH] Configured hInternet: 0x%.8x", remote->hInternet);

	
	// The InternetCrackUrl method was poorly designed...
	memset(tmpHostName, 0, sizeof(tmpHostName));
	memset(tmpUrlPath, 0, sizeof(tmpUrlPath));

	memset(&bits, 0, sizeof(bits));
	bits.dwStructSize = sizeof(bits);
	bits.dwHostNameLength  = sizeof(tmpHostName) -1;
	bits.lpszHostName      = tmpHostName;
	bits.dwUrlPathLength   = sizeof(tmpUrlPath) -1;
	bits.lpszUrlPath       = tmpUrlPath;

	InternetCrackUrl(remote->url, 0, 0, &bits);

	remote->uri = _strdup(tmpUrlPath);

	dprintf("[DISPATCH] Configured URL: %s", remote->uri);
	dprintf("[DISPATCH] Host: %s Port: %u", tmpHostName, bits.nPort);

	// Allocate the connection handle
	remote->hConnection = InternetConnect(remote->hInternet, tmpHostName, bits.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
	if (!remote->hConnection) {
		dprintf("[DISPATCH] Failed InternetConnect: %d", GetLastError());
		return 0;
	}
	dprintf("[DISPATCH] Configured hConnection: 0x%.8x", remote->hConnection);

	//authentication
	if (!(strcmp(global_meterpreter_proxy_username, "METERPRETER_USERNAME_PROXY") == 0))
	{
		InternetSetOption(remote->hConnection, INTERNET_OPTION_PROXY_USERNAME, global_meterpreter_proxy_username, (DWORD)strlen(global_meterpreter_proxy_username)+1);
		InternetSetOption(remote->hConnection, INTERNET_OPTION_PROXY_PASSWORD, global_meterpreter_proxy_password, (DWORD)strlen(global_meterpreter_proxy_password)+1);
		dprintf("[DISPATCH] Proxy authentication configured : %s/%s", global_meterpreter_proxy_username, global_meterpreter_proxy_password);
	}

	// Bring up the scheduler subsystem.
	result = scheduler_initialize( remote );
	if( result != ERROR_SUCCESS )
		return result;

	while( TRUE )
	{
		if (remote->comm_timeout != 0 && remote->comm_last_packet + remote->comm_timeout < current_unix_timestamp()) {
			dprintf("[DISPATCH] Shutting down server due to communication timeout");
			break;
		}

		if (remote->expiration_time != 0 && remote->expiration_time < current_unix_timestamp()) {
			dprintf("[DISPATCH] Shutting down server due to hardcoded expiration time");
			dprintf("Timestamp: %u  Expiration: %u", current_unix_timestamp(), remote->expiration_time);
			break;
		}

		if( event_poll( serverThread->sigterm, 0 ) )
		{
			dprintf( "[DISPATCH] server dispatch thread signaled to terminate..." );
			break;
		}

		dprintf("[DISPATCH] Reading data from the remote side...");
		result = packet_receive( remote, &packet );
		if( result != ERROR_SUCCESS ) {

			// Update the timestamp for empty replies
			if (result == ERROR_EMPTY) 
				remote->comm_last_packet = current_unix_timestamp();

			if (ecount < 10)
				delay = 10 * ecount;
			else 
				delay = 100 * ecount;
			
			ecount++;

			dprintf("[DISPATCH] no pending packets, sleeping for %dms...", min(10000, delay));
			Sleep( min(10000, delay) );
			continue;
		}

		remote->comm_last_packet = current_unix_timestamp();

		// Reset the empty count when we receive a packet
		ecount = 0;

		dprintf("[DISPATCH] Returned result: %d", result);

		cpt = thread_create( command_process_thread, remote, packet );
		if( cpt )
		{
			dprintf( "[DISPATCH] created command_process_thread 0x%08X, handle=0x%08X", cpt, cpt->handle );
			thread_run( cpt );
		}	
	}

	// Close WinInet handles
	InternetCloseHandle(remote->hConnection);
	InternetCloseHandle(remote->hInternet);

	dprintf( "[DISPATCH] calling scheduler_destroy..." );
	scheduler_destroy();

	dprintf( "[DISPATCH] calling command_join_threads..." );
	command_join_threads();

	dprintf( "[DISPATCH] leaving server_dispatch." );

	return result;
}
Ejemplo n.º 19
0
/**
 * main function for FOSSology scheduler, does command line parsing,
 * Initialization and then simply enters the event loop.
 *
 * @param argc the command line argument cound
 * @param argv the command line argument values
 * @return if the program ran correctly
 */
int main(int argc, char** argv)
{
  /* locals */
  gboolean db_reset = FALSE;  // flag to reset the job queue upon database connection
  gboolean ki_kill  = FALSE;  // flag that indicates all schedulers should be forcibly shutdown
  gboolean ki_shut  = FALSE;  // flag that indicates all schedulers should be gracefully shutdown
  gboolean db_init  = FALSE;  // flag indicating a database test
  gboolean test_die = FALSE;  // flag to run the tests then die
  gboolean s_daemon = FALSE;  // falg to run the scheduler as a daemon
  gchar* logdir = NULL;       // used when a different log from the default is used
  GOptionContext* options;    // option context used for command line parsing
  GError* error = NULL;       // error object used during parsing
  uint16_t port = 0;
  gchar* sysconfigdir = DEFAULT_SETUP;

  /* THE SCHEDULER */
  scheduler_t* scheduler;

  if(getenv("FO_SYSCONFDIR") != NULL)
    sysconfigdir = getenv("FO_SYSCONFDIR");

  /* get this done first */
  srand(time(NULL));
#if !(GLIB_MAJOR_VERSION >= 2 && GLIB_MINOR_VERSION >= 32)
  g_thread_init(NULL);
#endif
#if !(GLIB_MAJOR_VERSION >= 2 && GLIB_MINOR_VERSION >= 36)
  g_type_init();
#endif

  /* the options for the command line parser */
  GOptionEntry entries[] =
  {
      { "daemon",   'd', 0, G_OPTION_ARG_NONE,   &s_daemon,     "      Run scheduler as daemon"                       },
      { "database", 'i', 0, G_OPTION_ARG_NONE,   &db_init,      "      Initialize database connection and exit"       },
      { "kill",     'k', 0, G_OPTION_ARG_NONE,   &ki_kill,      "      Forcibly kills all running schedulers"         },
      { "shutdown", 's', 0, G_OPTION_ARG_NONE,   &ki_shut,      "      Gracefully shutdown of all running schedulers" },
      { "log",      'L', 0, G_OPTION_ARG_STRING, &logdir,       "[str] Specify location of log file"                  },
      { "port",     'p', 0, G_OPTION_ARG_INT,    &port,         "[num] Set the interface port"                        },
      { "reset",    'R', 0, G_OPTION_ARG_NONE,   &db_reset,     "      Reset the job queue upon startup"              },
      { "test",     't', 0, G_OPTION_ARG_NONE,   &test_die,     "      Close the scheduler after running tests"       },
      { "verbose",  'v', 0, G_OPTION_ARG_INT,    &verbose,      "[num] Set the scheduler verbose level"               },
      { "config",   'c', 0, G_OPTION_ARG_STRING, &sysconfigdir, "[str] Specify system configuration directory"        },
      {NULL}
  };

  /* ********************* */
  /* *** parse options *** */
  /* ********************* */
  options = g_option_context_new("- scheduler for FOSSology");
  g_option_context_add_main_entries(options, entries, NULL);
  g_option_context_parse(options, &argc, &argv, &error);

  if(error)
  {
    fprintf(stderr, "ERROR: %s\n", error->message);
    fprintf(stderr, "%s", g_option_context_get_help(options, FALSE, NULL));
    fflush(stderr);
    return -1;
  }

  g_option_context_free(options);

  /* check changes to the process first */
  if(ki_shut) { return kill_scheduler(FALSE); }
  if(ki_kill) { return kill_scheduler(TRUE);  }

  /* initialize the scheduler */
  scheduler = scheduler_init(sysconfigdir,
      log_new("stdout", "initializing", getpid()));

  if(logdir)
  {
    scheduler->logdir     = logdir;
    scheduler->logcmdline = TRUE;
    scheduler->main_log   = log_new(scheduler->logdir, NULL, scheduler->s_pid);

    log_destroy(main_log);
    main_log = scheduler->main_log;
  }

  scheduler->process_name = g_strdup(argv[0]);
  scheduler->s_daemon     = s_daemon;

  scheduler_foss_config(scheduler);
  if(s_daemon && scheduler_daemonize(scheduler) == -1) { return -1; }
  scheduler_agent_config(scheduler);

  database_init(scheduler);
  email_init(scheduler);

  NOTIFY("*****************************************************************");
  NOTIFY("***                FOSSology scheduler started                ***");
  NOTIFY("***        pid:      %-33d        ***", getpid());
  NOTIFY("***        verbose:  %-33d        ***", verbose);
  NOTIFY("***        config:   %-33s        ***", sysconfigdir);
  NOTIFY("*****************************************************************");

  interface_init(scheduler);
  fo_RepOpenFull(scheduler->sysconfig);

  signal(SIGCHLD, scheduler_sig_handle);
  signal(SIGTERM, scheduler_sig_handle);
  signal(SIGQUIT, scheduler_sig_handle);
  signal(SIGHUP,  scheduler_sig_handle);

  /* ***************************************************** */
  /* *** we have finished initialization without error *** */
  /* ***************************************************** */

  if(db_reset)
    database_reset_queue(scheduler);
  if(test_die)
    closing = 1;
  event_loop_enter(scheduler, scheduler_update, scheduler_signal);

  NOTIFY("*****************************************************************");
  NOTIFY("***                FOSSology scheduler closed                 ***");
  NOTIFY("***        pid:     %-34d        ***", scheduler->s_pid);
  NOTIFY("*****************************************************************\n");

  interface_destroy(scheduler);
  scheduler_destroy(scheduler);
  return 0;
}
/*!
 * @brief Setup and run the server. This is called from Init via the loader.
 * @param fd The original socket descriptor passed in from the stager, or a pointer to stageless extensions.
 * @return Meterpreter exit code (ignored by the caller).
 */
DWORD server_setup(MetsrvConfig* config)
{
	THREAD* serverThread = NULL;
	Remote* remote = NULL;
	char stationName[256] = { 0 };
	char desktopName[256] = { 0 };
	DWORD res = 0;

	dprintf("[SERVER] Initializing from configuration: 0x%p", config);
	dprintf("[SESSION] Comms Fd: %u", config->session.comms_fd);
	dprintf("[SESSION] Expiry: %u", config->session.expiry);

	dprintf("[SERVER] UUID: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
		config->session.uuid[0], config->session.uuid[1], config->session.uuid[2], config->session.uuid[3],
		config->session.uuid[4], config->session.uuid[5], config->session.uuid[6], config->session.uuid[7],
		config->session.uuid[8], config->session.uuid[9], config->session.uuid[10], config->session.uuid[11],
		config->session.uuid[12], config->session.uuid[13], config->session.uuid[14], config->session.uuid[15]);

	// if hAppInstance is still == NULL it means that we havent been
	// reflectivly loaded so we must patch in the hAppInstance value
	// for use with loading server extensions later.
	InitAppInstance();

	srand((unsigned int)time(NULL));

	__try
	{
		do
		{
			dprintf("[SERVER] module loaded at 0x%08X", hAppInstance);

			// Open a THREAD item for the servers main thread, we use this to manage migration later.
			serverThread = thread_open();

			dprintf("[SERVER] main server thread: handle=0x%08X id=0x%08X sigterm=0x%08X", serverThread->handle, serverThread->id, serverThread->sigterm);

			if (!(remote = remote_allocate()))
			{
				SetLastError(ERROR_NOT_ENOUGH_MEMORY);
				break;
			}

			setup_ssl_lib(&remote->ssl);

			remote->orig_config = config;
			remote->sess_expiry_time = config->session.expiry;
			remote->sess_start_time = current_unix_timestamp();
			remote->sess_expiry_end = remote->sess_start_time + config->session.expiry;

			dprintf("[DISPATCH] Session going for %u seconds from %u to %u", remote->sess_expiry_time, remote->sess_start_time, remote->sess_expiry_end);

			DWORD transportSize = 0;
			if (!create_transports(remote, config->transports, &transportSize))
			{
				// not good, bail out!
				SetLastError(ERROR_BAD_ARGUMENTS);
				break;
			}

			// the first transport should match the transport that we initially connected on.
			// If it's TCP comms, we need to wire that up.
			if (remote->transport->type == METERPRETER_TRANSPORT_SSL && config->session.comms_fd)
			{
				((TcpTransportContext*)remote->transport->ctx)->fd = (SOCKET)config->session.comms_fd;
			}

			// Set up the transport creation function pointer
			remote->trans_create = create_transport;
			// Set up the transport removal function pointer
			remote->trans_remove = remove_transport;
			// and the config creation pointer
			remote->config_create = config_create;

			// Store our thread handle
			remote->server_thread = serverThread->handle;

			dprintf("[SERVER] Registering dispatch routines...");
			register_dispatch_routines();

			// this has to be done after dispatch routine are registered
			load_stageless_extensions(remote, (MetsrvExtension*)((LPBYTE)config->transports + transportSize));

			// Store our process token
			if (!OpenThreadToken(remote->server_thread, TOKEN_ALL_ACCESS, TRUE, &remote->server_token))
			{
				OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &remote->server_token);
			}

			if (scheduler_initialize(remote) != ERROR_SUCCESS)
			{
				SetLastError(ERROR_BAD_ENVIRONMENT);
				break;
			}

			// Copy it to the thread token
			remote->thread_token = remote->server_token;

			// Save the initial session/station/desktop names...
			remote->orig_sess_id = server_sessionid();
			remote->curr_sess_id = remote->orig_sess_id;
			GetUserObjectInformation(GetProcessWindowStation(), UOI_NAME, &stationName, 256, NULL);
			remote->orig_station_name = _strdup(stationName);
			remote->curr_station_name = _strdup(stationName);
			GetUserObjectInformation(GetThreadDesktop(GetCurrentThreadId()), UOI_NAME, &desktopName, 256, NULL);
			remote->orig_desktop_name = _strdup(desktopName);
			remote->curr_desktop_name = _strdup(desktopName);

			remote->sess_start_time = current_unix_timestamp();

			// loop through the transports, reconnecting each time.
			while (remote->transport)
			{
				if (remote->transport->transport_init)
				{
					dprintf("[SERVER] attempting to initialise transport 0x%p", remote->transport);
					// Each transport has its own set of retry settings and each should honour
					// them individually.
					if (!remote->transport->transport_init(remote->transport))
					{
						dprintf("[SERVER] transport initialisation failed, moving to the next transport");
						remote->transport = remote->transport->next_transport;

						// when we have a list of transports, we'll iterate to the next one.
						continue;
					}
				}

				dprintf("[SERVER] Entering the main server dispatch loop for transport %x, context %x", remote->transport, remote->transport->ctx);
				DWORD dispatchResult = remote->transport->server_dispatch(remote, serverThread);

				dprintf("[DISPATCH] dispatch exited with result: %u", dispatchResult);
				if (remote->transport->transport_deinit)
				{
					dprintf("[DISPATCH] deinitialising transport");
					remote->transport->transport_deinit(remote->transport);
				}

				dprintf("[TRANS] resetting transport");
				if (remote->transport->transport_reset)
				{
					remote->transport->transport_reset(remote->transport, dispatchResult == ERROR_SUCCESS && remote->next_transport == NULL);
				}

				// If the transport mechanism failed, then we should loop until we're able to connect back again.
				if (dispatchResult == ERROR_SUCCESS)
				{
					dprintf("[DISPATCH] Server requested shutdown of dispatch");
					// But if it was successful, and this is a valid exit, then we should clean up and leave.
					if (remote->next_transport == NULL)
					{
						dprintf("[DISPATCH] No next transport specified, leaving");
						// we weren't asked to switch transports, so we exit.
						break;
					}

					// we need to change transports to the one we've been given. We will assume, for now,
					// that the transport has been created using the appropriate functions and that it is
					// part of the transport list.
					dprintf("[TRANS] Moving transport from 0x%p to 0x%p", remote->transport, remote->next_transport);
					remote->transport = remote->next_transport;
					remote->next_transport = NULL;

				}
				else
				{
					// move to the next one in the list
					dprintf("[TRANS] Moving transport from 0x%p to 0x%p", remote->transport, remote->transport->next_transport);
					remote->transport = remote->transport->next_transport;
				}

				// transport switching and failover both need to support the waiting functionality.
				if (remote->next_transport_wait > 0)
				{
					dprintf("[TRANS] Sleeping for %u seconds ...", remote->next_transport_wait);

					sleep(remote->next_transport_wait);

					// the wait is a once-off thing, needs to be reset each time
					remote->next_transport_wait = 0;
				}
			}

			// clean up the transports
			while (remote->transport)
			{
				remove_transport(remote, remote->transport);
			}

			dprintf("[SERVER] Deregistering dispatch routines...");
			deregister_dispatch_routines(remote);
		} while (0);

		dprintf("[DISPATCH] calling scheduler_destroy...");
		scheduler_destroy();

		dprintf("[DISPATCH] calling command_join_threads...");
		command_join_threads();

		remote_deallocate(remote);
	}
	__except (exceptionfilter(GetExceptionCode(), GetExceptionInformation()))
	{
		dprintf("[SERVER] *** exception triggered!");

		thread_kill(serverThread);
	}

	dprintf("[SERVER] Finished.");
	return res;
}
Ejemplo n.º 21
0
void test_event_loop_enter()
{
  scheduler_t* scheduler;
  scheduler = scheduler_init(testdb, NULL);
  scheduler_agent_config(scheduler);

  event_loop_t* vl = event_loop_get();
  int retval = 0;

  call_num = 0;
  samp_num = 0;
  event_signal(NULL, NULL);
  event_signal(terminate_event, NULL);

  retval = event_loop_enter(scheduler, sample_callback, NULL);
  FO_ASSERT_EQUAL(retval, 0x0);
  FO_ASSERT_EQUAL(call_num,1);
  FO_ASSERT_TRUE(vl->terminated);
  FO_ASSERT_FALSE(vl->occupied);

  event_signal(sample_event, NULL);
  event_signal(terminate_event, NULL);

  retval = event_loop_enter(scheduler, sample_callback, NULL);
  FO_ASSERT_EQUAL(retval, 0x0);
  FO_ASSERT_EQUAL(samp_num, 1);
  FO_ASSERT_EQUAL(call_num, 3);

  vl->occupied = 0;
  vl->terminated = 0;
  event_signal(terminate_event, NULL);

  retval = event_loop_enter(scheduler, sample_callback, NULL);
  FO_ASSERT_EQUAL(retval, 0x0);
  FO_ASSERT_EQUAL(samp_num, 1);
  FO_ASSERT_EQUAL(call_num, 4);

  vl->occupied = 0;
  vl->terminated = 0;
  samp_num = 0;
  call_num = 0;

  event_signal(sample_event, NULL);
  event_signal(sample_event, NULL);
  event_signal(other_event, NULL);
  event_signal(sample_event, NULL);
  event_signal(sample_event, NULL);
  event_signal(other_event, NULL);
  event_signal(terminate_event, NULL);

  retval = event_loop_enter(scheduler, sample_callback, NULL);
  FO_ASSERT_EQUAL(retval, 0x0);
  FO_ASSERT_EQUAL(samp_num, 2);
  FO_ASSERT_EQUAL(call_num, 7);

  vl->occupied = 0;
  vl->terminated = 1;
  samp_num = 0;
  call_num = 0;

  event_signal(sample_event, NULL);
  event_signal(sample_event, NULL);
  event_signal(other_event, NULL);
  event_signal(sample_event, NULL);
  event_signal(sample_event, NULL);
  event_signal(other_event, NULL);
  event_signal(terminate_event, NULL);

  retval = event_loop_enter(scheduler, sample_callback, NULL);
  FO_ASSERT_EQUAL(retval, 0x0);
  FO_ASSERT_EQUAL(samp_num, 2);
  FO_ASSERT_EQUAL(call_num, 7);

  scheduler_destroy(scheduler);
}