VGAuthError
SAMLVerifyAssertion(const char *xmlText,
                    SAMLTokenData &token,
                    vector<string> &certs)
{
   XercesDOMParser parser(NULL, XMLPlatformUtils::fgMemoryManager, pool);
   SAMLErrorHandler errorHandler;
   SecurityManager sm;

   parser.setErrorHandler(&errorHandler);

   // prevent the billion laughs attack -- put a limit on entity expansions
   sm.setEntityExpansionLimit(100);
   parser.setSecurityManager(&sm);

   DOMDocument *doc = SAMLValidateSchemaAndParse(parser, xmlText);
   if (NULL == doc) {
      return VGAUTH_E_AUTHENTICATION_DENIED;
   }

   const DOMElement *s = SAMLFindChildByName(doc->getDocumentElement(),
                                             SAML_TOKEN_PREFIX"Subject");
   if (NULL == s) {
      Debug("Couldn't find " SAML_TOKEN_PREFIX " in token\n");
      s = SAMLFindChildByName(doc->getDocumentElement(),
                                             SAML_TOKEN_SSO_PREFIX"Subject");
      if (NULL == s) {
         Debug("Couldn't find " SAML_TOKEN_SSO_PREFIX " in token\n");
         Warning("No recognized tags in token; punting\n");
         return VGAUTH_E_AUTHENTICATION_DENIED;
      } else {
         Debug("Found " SAML_TOKEN_SSO_PREFIX " in token\n");
         token.isSSOToken = true;
         token.ns = SAML_TOKEN_SSO_PREFIX;
      }
   } else {
      Debug("Found " SAML_TOKEN_PREFIX " in token\n");
      token.isSSOToken = false;
      token.ns = SAML_TOKEN_PREFIX;
   }

   if (!SAMLCheckSubject(doc, token)) {
      return VGAUTH_E_AUTHENTICATION_DENIED;
   }

   if (!SAMLCheckConditions(doc, token)) {
      return VGAUTH_E_AUTHENTICATION_DENIED;
   }

   if (!SAMLCheckSignature(doc, certs)) {
      return VGAUTH_E_AUTHENTICATION_DENIED;
   }

   return VGAUTH_E_OK;
}
示例#2
0
Result<ExitCode> ProcessAsUser::Run(const Settings& settings, ProcessTracker& processTracker) const
{
	Trace trace(settings.GetLogLevel());
	trace < L"ProcessAsUser::Attempt to log a user on to the local computer";
	StringBuffer userName(settings.GetUserName());
	StringBuffer domain(settings.GetDomain());
	StringBuffer password(settings.GetPassword());
	StringBuffer workingDirectory(settings.GetWorkingDirectory());
	StringBuffer commandLine(settings.GetCommandLine());

	SecurityManager securityManager;
	auto setPrivilegesResult = securityManager.SetPrivileges(trace, { SE_TCB_NAME, SE_ASSIGNPRIMARYTOKEN_NAME }, true);
	if(setPrivilegesResult.HasError())
	{
		return setPrivilegesResult.GetError();
	}

	auto newUserSecurityTokenHandle = Handle(L"New user security token");
	unsigned long logonTypeCount = sizeof(allLogonTypes) / sizeof(allLogonTypes[0]);
	for (unsigned long logonTypeIndex = 0; logonTypeIndex < logonTypeCount; logonTypeIndex++)
	{
		auto logonType = allLogonTypes[logonTypeIndex];
		trace < L"::LogonUser using logon type ";
		switch (logonType)
		{
			case LOGON32_LOGON_INTERACTIVE:
				trace << L"LOGON32_LOGON_INTERACTIVE";
				break;

			case LOGON32_LOGON_NETWORK:
				trace << L"LOGON32_LOGON_NETWORK";
				break;

			case LOGON32_LOGON_BATCH:
				trace << L"LOGON32_LOGON_BATCH";
				break;

			case LOGON32_LOGON_SERVICE:
				trace << L"LOGON32_LOGON_SERVICE";
				break;
		}

		if (LogonUser(
			userName.GetPointer(),
			domain.GetPointer(),
			password.GetPointer(),
			logonType,
			LOGON32_PROVIDER_DEFAULT,
			&newUserSecurityTokenHandle))
		{
			break;
		}
		
		auto error = Error(L"LogonUser");
		trace << L" - ";
		trace << error.GetDescription();

		if(logonTypeIndex == logonTypeCount -1)
		{
			return error;
		}
	}

	trace < L"ProcessAsUser::InitializeConsoleRedirection a new security descriptor";
	trace < L"::InitializeSecurityDescriptor";
	SECURITY_DESCRIPTOR securityDescriptor = {};
	if (!InitializeSecurityDescriptor(
		&securityDescriptor,
		SECURITY_DESCRIPTOR_REVISION))
	{
		return Error(L"InitializeSecurityDescriptor");
	}

	trace < L"::SetSecurityDescriptorDacl";
	if (!SetSecurityDescriptorDacl(
		&securityDescriptor,
		true,
		nullptr,
		false))
	{
		return Error(L"SetSecurityDescriptorDacl");
	}

	trace < L"ProcessAsUser::Creates a new access primary token that duplicates new process's token";
	auto primaryNewUserSecurityTokenHandle = Handle(L"Primary new user security token");
	SECURITY_ATTRIBUTES processSecAttributes = {};
	processSecAttributes.lpSecurityDescriptor = &securityDescriptor;
	processSecAttributes.nLength = sizeof(SECURITY_DESCRIPTOR);
	processSecAttributes.bInheritHandle = true;
	trace < L"::DuplicateTokenEx";
	if (!DuplicateTokenEx(
		newUserSecurityTokenHandle,
		0, // MAXIMUM_ALLOWED
		&processSecAttributes,
		SecurityImpersonation,
		TokenPrimary,
		&primaryNewUserSecurityTokenHandle))
	{
		return Error(L"DuplicateTokenEx");
	}	

	SECURITY_ATTRIBUTES threadSecAttributes = {};
	threadSecAttributes.lpSecurityDescriptor = nullptr;
	threadSecAttributes.nLength = 0;
	threadSecAttributes.bInheritHandle = false;	
	STARTUPINFO startupInfo = {};	

	trace < L"ProcessTracker::InitializeConsoleRedirection";
	auto error = processTracker.InitializeConsoleRedirection(processSecAttributes, startupInfo);
	if(error.HasError())
	{
		return Result<ExitCode>(error.GetError());
	}

	trace < L"::LoadUserProfile";
	PROFILEINFO profileInfo = {};
	profileInfo.dwSize = sizeof(PROFILEINFO);
	profileInfo.lpUserName = userName.GetPointer();
	if (!LoadUserProfile(primaryNewUserSecurityTokenHandle, &profileInfo))
	{
		return Error(L"LoadUserProfile");
	}

	auto newProcessEnvironmentResult = GetEnvironment(settings, primaryNewUserSecurityTokenHandle, settings.GetInheritanceMode(), trace);
	if (newProcessEnvironmentResult.HasError())
	{
		UnloadUserProfile(primaryNewUserSecurityTokenHandle, profileInfo.hProfile);
		return Result<ExitCode>(newProcessEnvironmentResult.GetError());
	}

	auto setIntegrityLevelResult = securityManager.SetIntegrityLevel(settings.GetIntegrityLevel(), primaryNewUserSecurityTokenHandle, trace);
	if (setIntegrityLevelResult.HasError())
	{
		return Result<ExitCode>(setIntegrityLevelResult.GetError());
	}

	trace < L"ProcessAsUser::Create a new process and its primary thread. The new process runs in the security context of the user represented by the specified token.";
	PROCESS_INFORMATION processInformation = {};
	startupInfo.dwFlags = STARTF_USESHOWWINDOW;
	startupInfo.wShowWindow = ShowModeConverter::ToShowWindowFlag(settings.GetShowMode());
	auto cmdLine = settings.GetCommandLine();
	trace < L"::CreateProcessAsUser";	
	if (!CreateProcessAsUser(
		primaryNewUserSecurityTokenHandle,
		nullptr,
		commandLine.GetPointer(),
		&processSecAttributes,
		&threadSecAttributes,
		true,
		CREATE_UNICODE_ENVIRONMENT,
		newProcessEnvironmentResult.GetResultValue().CreateEnvironment(),
		workingDirectory.GetPointer(),
		&startupInfo,
		&processInformation))
	{		
		auto result = Error(L"CreateProcessAsUser");
		UnloadUserProfile(primaryNewUserSecurityTokenHandle, profileInfo.hProfile);
		return result;
	}

	// ReSharper disable CppInitializedValueIsAlwaysRewritten
	// ReSharper disable CppEntityAssignedButNoRead
	
	auto processHandle = Handle(L"Service Process");
	processHandle = processInformation.hProcess;
	
	auto threadHandle = Handle(L"Thread");
	threadHandle = processInformation.hThread;

	auto exitCode = processTracker.WaiteForExit(processInformation.hProcess, trace);
	UnloadUserProfile(primaryNewUserSecurityTokenHandle, profileInfo.hProfile);	

	return exitCode;
}
示例#3
0
Result<ExitCode> ProcessWithLogon::RunInternal(Trace& trace, const Settings& settings, ProcessTracker& processTracker, Environment& environment, bool changeIntegrityLevel) const
{
	SECURITY_ATTRIBUTES securityAttributes = {};
	securityAttributes.nLength = sizeof(SECURITY_DESCRIPTOR);
	securityAttributes.bInheritHandle = true;

	STARTUPINFO startupInfo = {};
	startupInfo.dwFlags = STARTF_USESHOWWINDOW;
	startupInfo.wShowWindow = ShowModeConverter::ToShowWindowFlag(settings.GetShowMode());	
	PROCESS_INFORMATION processInformation = {};

	trace < L"ProcessTracker::InitializeConsoleRedirection";
	processTracker.InitializeConsoleRedirection(securityAttributes, startupInfo);	

	StringBuffer userName(settings.GetUserName());
	StringBuffer domain(settings.GetDomain());
	StringBuffer password(settings.GetPassword());
	StringBuffer workingDirectory(settings.GetWorkingDirectory());
	StringBuffer commandLine(settings.GetCommandLine());

	if (changeIntegrityLevel)
	{
		trace < L"::LogonUser";
		auto newUserSecurityTokenHandle = Handle(L"New user security token");
		if (!LogonUser(
			userName.GetPointer(),
			domain.GetPointer(),
			password.GetPointer(),
			LOGON32_LOGON_BATCH,
			LOGON32_PROVIDER_DEFAULT,
			&newUserSecurityTokenHandle))
		{
			return Error(L"LogonUser");
		}

		trace < L"::LoadUserProfile";
		PROFILEINFO profileInfo = {};
		profileInfo.dwSize = sizeof(PROFILEINFO);
		profileInfo.lpUserName = userName.GetPointer();
		if (!LoadUserProfile(newUserSecurityTokenHandle, &profileInfo))
		{
			return Error(L"LoadUserProfile");
		}

		SecurityManager securityManager;
		auto setIntegrityLevelResult = securityManager.SetIntegrityLevel(settings.GetIntegrityLevel(), newUserSecurityTokenHandle, trace);
		if (setIntegrityLevelResult.HasError())
		{
			return Result<ExitCode>(setIntegrityLevelResult.GetError());
		}

		trace < L"::CreateProcessWithTokenW";		
		if (!CreateProcessWithTokenW(
			newUserSecurityTokenHandle,
			LOGON_WITH_PROFILE,
			nullptr,
			commandLine.GetPointer(),
			CREATE_UNICODE_ENVIRONMENT,
			environment.CreateEnvironment(),
			workingDirectory.GetPointer(),
			&startupInfo,
			&processInformation))
		{
			return Error(L"CreateProcessWithLogonW");
		}
	}
	else
	{
		trace < L"::CreateProcessWithLogonW";		
		if (!CreateProcessWithLogonW(
			userName.GetPointer(),
			domain.GetPointer(),
			password.GetPointer(),
			LOGON_WITH_PROFILE,
			nullptr,
			commandLine.GetPointer(),
			CREATE_UNICODE_ENVIRONMENT,
			environment.CreateEnvironment(),
			workingDirectory.GetPointer(),
			&startupInfo,
			&processInformation))
		{
			return Error(L"CreateProcessWithLogonW");
		}
	}

	// ReSharper disable once CppInitializedValueIsAlwaysRewritten
	auto processHandle = Handle(L"Process");
	processHandle = processInformation.hProcess;

	// ReSharper disable once CppInitializedValueIsAlwaysRewritten
	auto threadHandle = Handle(L"Thread");
	threadHandle = processInformation.hThread;

	return processTracker.WaiteForExit(processInformation.hProcess, trace);
}
示例#4
0
int run_haggle()
{
	srand(time(NULL));
#ifdef ENABLE_DEBUG_MANAGER
	DebugManager *db = NULL;
#endif
	ApplicationManager *am = NULL;
	DataManager *dm = NULL;
// SW: START: SendPriorityManager
	SendPriorityManager *spm = NULL;
// SW: END: SendPriorityManager
	NodeManager *nm = NULL;
	ProtocolManager *pm = NULL;
	ForwardingManager *fm = NULL;
	SecurityManager *sm = NULL;
	ConnectivityManager *cm = NULL;
	LossEstimateManager *lm = NULL;
	NetworkCodingManager* networkCodingManager = NULL;
	FragmentationManager* fragmentationManager = NULL;
	//JM
	ReplicationManager *replicationManager = NULL;
	BenchmarkManager *bm = NULL;
	ResourceManager *rm = NULL;
// SW: START: interest manager
    InterestManager *im = NULL;
// SW: END: interest manager

	ProtocolSocket *p = NULL;
#ifdef OS_WINDOWS_MOBILE

	// For testing we force the deletion of the data store
	//recreateDataStore = true;
#endif
	int retval = EXIT_FAILURE;

#if defined(OS_ANDROID)
	//mallopt(-1, -1); // MOS - avoid trimming
#elif defined(OS_LINUX)
        mallopt(M_TRIM_THRESHOLD, -1); // MOS - avoid trimming
#endif

	xmlInitParser(); // MOS - this need to be called here for thread-safe libxml use

#ifdef DEBUG
    Trace::trace.enableFileTrace();
#endif

	HAGGLE_LOG("\n\n****************** HAGGLE STARTUP *********************\n\n");

	if (!create_path(HAGGLE_DEFAULT_STORAGE_PATH)) {
                HAGGLE_ERR("Could not create Haggle storage path : %s\n", HAGGLE_DEFAULT_STORAGE_PATH);
                return -1;
        }
	
        retval = write_pid_file(getpid());

        if (retval != HAGGLE_PROCESS_NO_ERROR) {
                switch (retval) {
                        case HAGGLE_PROCESS_BAD_PID:
                                HAGGLE_ERR("Cannot read PID file %s.\n", PID_FILE.c_str());
                                break;
                        case HAGGLE_PROCESS_CANNOT_WRITE_PID:
                                HAGGLE_ERR("Cannot write PID file %s\n", PID_FILE.c_str());
                                break;
                        case HAGGLE_PROCESS_ALREADY_RUNNING: 
                                HAGGLE_ERR("PID file %s indicates that Haggle is already running.\n", PID_FILE.c_str());
                                break;
                        default:
                                HAGGLE_ERR("Unknown PID file error\n");

                }
                shouldCleanupPidFile = false;
                return -1;
        }
#if defined(OS_UNIX) && !defined(OS_ANDROID)
	setrawtty();
#endif
      
        /* Seed the random number generator */
	prng_init();

// SW: START CONFIG PATH (instead of hardcoded ~/.Haggle/config.xml),
    if (useMemoryDB) {
        kernel = new HaggleKernel(configFile, new MemoryDataStore(recreateDataStore));
    }
    else {
        kernel = new HaggleKernel(configFile, new SQLDataStore(recreateDataStore));
    }
// SW: END CONFIG PATH.

	if (!kernel || !kernel->init()) {
		fprintf(stderr, "Kernel initialization error!\n");
		return -1;
	}
	
	// Build a Haggle configuration
	am = new ApplicationManager(kernel);

	if (!am || !am->init()) {
		HAGGLE_ERR("Could not initialize application manager\n");
		goto finish;
	}

	dm = new DataManager(kernel, setCreateTimeOnBloomfilterUpdate);

	if (!dm || !dm->init()) {
		HAGGLE_ERR("Could not initialize data manager\n");
		goto finish;
	}

// SW: START: SendPriorityManager
    spm = new SendPriorityManager(kernel);
    if (!spm || !spm->init()) {
        HAGGLE_ERR("Could not initialize send priority manager\n");
        goto finish;
    }
// SW: END: SendPriorityManager

	nm = new NodeManager(kernel);

	if (!nm || !nm->init()) {
		HAGGLE_ERR("Could not initialize node manager\n");
		goto finish;
	}

	pm = new ProtocolManager(kernel);

	if (!pm || !pm->init()) {
		HAGGLE_ERR("Could not initialize protocol manager\n");
		goto finish;
	}

	fm = new ForwardingManager(kernel);

	if (!fm || !fm->init()) {
		HAGGLE_ERR("Could not initialize forwarding manager\n");
		goto finish;
	}

	sm = new SecurityManager(kernel, securityLevel);

	if (!sm || !sm->init()) {
		HAGGLE_ERR("Could not initialize security manager\n");
		goto finish;
	}
	fragmentationManager = new FragmentationManager(kernel);
	if(!fragmentationManager || !fragmentationManager->init()) {
	    HAGGLE_ERR("Could not initialize fragmentationManager\n");
	    goto finish;
	}

	networkCodingManager = new NetworkCodingManager(kernel);
	if(!networkCodingManager || !networkCodingManager->init()) {
	    HAGGLE_ERR("Could not initialize networkCodingManager \n");
	    goto finish;
	}

	//JM
	replicationManager = new ReplicationManager(kernel);
        if (!replicationManager || !replicationManager->init()) {
		HAGGLE_ERR("Could not initialize replication manager\n");
		goto finish;
    }
    
	lm = new LossEstimateManager(kernel);
	if(!lm || !lm->init()){
	    HAGGLE_ERR("Could not initialize LossEstimateManager \n");
	    goto finish;		
	}

#ifdef USE_UNIX_APPLICATION_SOCKET
	p = new ProtocolLOCAL(kernel->getStoragePath() + "/" + HAGGLE_LOCAL_SOCKET, pm);

	if (!p || !p->init()) {
		HAGGLE_ERR("Could not initialize LOCAL protocol\n");
		goto finish;
	}
	p->setFlag(PROT_FLAG_APPLICATION);
	p->registerWithManager();

#endif
	p = new ProtocolUDP("127.0.0.1", HAGGLE_SERVICE_DEFAULT_PORT, pm);
	/* Add ConnectivityManager last since it will start to
	* discover interfaces and generate events. At that
	* point the other managers should already be
	* running. */

	if (!p || !p->init()) {
		HAGGLE_ERR("Could not initialize UDP Application protocol\n");
		goto finish;
	}
	p->setFlag(PROT_FLAG_APPLICATION);
	p->registerWithManager();

// SW: start interest manager
    im = new InterestManager(kernel);

    if (!im || !im->init()) {
        HAGGLE_ERR("Could not initialize interest manager\n");
        goto finish;
    }
// SW: end interest manager

	/* MOS - disable resource mananager due 
	   high cpu utilization bug on Android

	rm = new ResourceManager(kernel);

	if (!rm || !rm->init()) {
		HAGGLE_ERR("Could not initialize resource manager\n");
		goto finish;
	}

	*/

	if (!isBenchmarking) {
		cm = new ConnectivityManager(kernel);

		if (!cm || !cm->init()) {
			HAGGLE_ERR("Could not initialize connectivity manager\n");
			goto finish;
		}

	} else {
		bm = new BenchmarkManager(kernel, Benchmark_DataObjects_Attr, Benchmark_Nodes_Attr, Benchmark_Attr_Num, Benchmark_DataObjects_Num, Benchmark_Test_Num);

		if (!bm || !bm->init()) {
			HAGGLE_ERR("Could not initialize benchmark manager\n");
			goto finish;
		}
	}
#if defined(ENABLE_DEBUG_MANAGER)
	// It seems as if there can be only one accept() per
	// thread... we need to make the DebugManager register
	// protocol or something with the ProtocolTCPServer
	// somehow
	db = new DebugManager(kernel, runAsInteractive);

	if (!db || !db->init()) {
		HAGGLE_ERR("Could not initialize debug manager\n");
		/* Treat as non critical error. */
	}
#endif

	HAGGLE_DBG("Starting Haggle...\n");

#ifdef OS_WINDOWS_MOBILE
	if (platform_type(current_platform()) == platform_windows_mobile_professional)
		tray_notification_add(g_hInstance, kernel);
#endif

	kernel->run();

	if(kernel->hasFatalError()) retval = EXIT_FAILURE;
	else retval = EXIT_SUCCESS;

	HAGGLE_DBG("Haggle finished...\n");

finish:
	if (bm)
		delete bm;
	if (lm)
		delete lm;

	if (fragmentationManager) {
	    delete fragmentationManager;
	    fragmentationManager = NULL;
	}
	if (networkCodingManager)
	    delete networkCodingManager;
	//JM
	if (replicationManager)
	  	delete replicationManager;
	if (cm)
		delete cm;
	if (sm)
		delete sm;
	if (fm)
		delete fm;
	if (pm)	
		delete pm;
	if (nm)
		delete nm;
	if (dm)
		delete dm;
// SW: START: SendPriorityManager
    if (spm)
        delete spm;
// SW: END: SendPriorityManager
	if (am)
		delete am;
// SW: start interest manager
    if (im)
        delete im;
// SW: end interest manager
#if defined(ENABLE_DEBUG_MANAGER)
	if (db)
		delete db;
#endif
	if (rm)
		delete rm;

#ifdef OS_WINDOWS_MOBILE
	tray_notification_remove();
#endif
	delete kernel;
	kernel = NULL;

	xmlCleanupParser(); // MOS

	return retval;
}
示例#5
0
/**
 * Retrieve a ::REQUIRES file.  This will cache the entries so
 * that the same requires entry is returned for every request.
 *
 * @param activity  The current activity.
 * @param shortName The short name of the package.
 * @param resolvedName
 *                  The fully resolved name of a potential package file.  The short
 *                  name is used for checking in the MacroSpace, the long name
 *                  is used for file searches.
 * @param result    The return package routine.
 *
 * @return The package routine (also returned in the result protected object).
 */
RoutineClass *PackageManager::loadRequires(RexxActivity *activity, RexxString *shortName, RexxString *resolvedName, ProtectedObject &result)
{
    result = OREF_NULL;

    SecurityManager *manager = activity->getEffectiveSecurityManager();
    RexxObject *securityManager = OREF_NULL;

    shortName = manager->checkRequiresAccess(shortName, securityManager);
    // no return means forbidden access to this name.  Just return
    // nothing
    if (shortName == OREF_NULL)
    {
        return OREF_NULL;
    }


    // first check this using the specified name.  Since we need to perform checks in the
    // macro space, it's possible this will be loaded under the simple name.  We'll need to check
    // table again using the fully resolved name afterward.

    RoutineClass *package = checkRequiresCache(shortName, result);
    if (package != OREF_NULL)
    {
        return package;
    }

    unsigned short macroPosition;    // a macrospace position marker

    // we need to look in the macrospace before we try checking for a file-based
    // requires.  The macrospace version uses the original name for all checks.  Once we
    // get to the file-based version, we switch to the full resolved name.
    bool checkMacroSpace = RexxQueryMacro(shortName->getStringData(), &macroPosition) == 0;
    if (checkMacroSpace && (macroPosition == RXMACRO_SEARCH_BEFORE))
    {
        return getMacroSpaceRequires(activity, shortName, result, securityManager);
    }

    // it's possible we don't have a file version of this
    if (resolvedName != OREF_NULL)
    {
        resolvedName = manager->checkRequiresAccess(resolvedName, securityManager);
        // no return means forbidden access to this name.  Just return
        // nothing
        if (resolvedName == OREF_NULL)
        {
            return OREF_NULL;
        }


        // now check again using the longer name
        package = checkRequiresCache(resolvedName, result);
        if (package != OREF_NULL)
        {
            return package;
        }

        // load the file version of this.
        return getRequiresFile(activity, resolvedName, securityManager, result);
    }

    // do the macrospace after checks
    if (checkMacroSpace)
    {
        return getMacroSpaceRequires(activity, shortName, result, securityManager);
    }

    // nothing to return
    return OREF_NULL;
}
示例#6
0
int run_haggle()
{
#ifdef ENABLE_DEBUG_MANAGER
	DebugManager *db = NULL;
#endif
	ApplicationManager *am = NULL;
	DataManager *dm = NULL;
	NodeManager *nm = NULL;
	ProtocolManager *pm = NULL;
	ForwardingManager *fm = NULL;
	SecurityManager *sm = NULL;
	ConnectivityManager *cm = NULL;
#ifdef BENCHMARK
	BenchmarkManager *bm = NULL;
	//recreateDataStore = true;
#endif
	ResourceManager *rm = NULL;
	ProtocolSocket *p = NULL;
#ifdef OS_WINDOWS_MOBILE

	// For testing we force the deletion of the data store
	//recreateDataStore = true;
#endif
	int retval = EXIT_FAILURE;
	  
	if (!create_path(HAGGLE_DEFAULT_STORAGE_PATH)) {
                HAGGLE_ERR("Could not create Haggle storage path : %s\n", HAGGLE_DEFAULT_STORAGE_PATH);
                return -1;
        }
	
        retval = write_pid_file(getpid());

        if (retval != HAGGLE_PROCESS_NO_ERROR) {
                switch (retval) {
                        case HAGGLE_PROCESS_BAD_PID:
                                HAGGLE_ERR("Cannot read PID file %s.\n", PID_FILE.c_str());
                                break;
                        case HAGGLE_PROCESS_CANNOT_WRITE_PID:
                                HAGGLE_ERR("Cannot write PID file %s\n", PID_FILE.c_str());
                                break;
                        case HAGGLE_PROCESS_ALREADY_RUNNING: 
                                HAGGLE_ERR("PID file %s indicates that Haggle is already running.\n", PID_FILE.c_str());
                                break;
                        default:
                                HAGGLE_ERR("Unknown PID file error\n");

                }
                shouldCleanupPidFile = false;
                return -1;
        }
#if defined(OS_UNIX) && !defined(OS_ANDROID)
	setrawtty();
#endif
      
        /* Seed the random number generator */
	prng_init();

        kernel = new HaggleKernel(new SQLDataStore(recreateDataStore));

	if (!kernel || !kernel->init()) {
		fprintf(stderr, "Kernel initialization error!\n");
		return -1;
	}
	
	// Build a Haggle configuration
	am = new ApplicationManager(kernel);

	if (!am || !am->init()) {
		HAGGLE_ERR("Could not initialize application manager\n");
		goto finish;
	}

	dm = new DataManager(kernel, setCreateTimeOnBloomfilterUpdate);

	if (!dm || !dm->init()) {
		HAGGLE_ERR("Could not initialize data manager\n");
		goto finish;
	}

	nm = new NodeManager(kernel);

	if (!nm || !nm->init()) {
		HAGGLE_ERR("Could not initialize node manager\n");
		goto finish;
	}

	pm = new ProtocolManager(kernel);

	if (!pm || !pm->init()) {
		HAGGLE_ERR("Could not initialize protocol manager\n");
		goto finish;
	}

	fm = new ForwardingManager(kernel);

	if (!fm || !fm->init()) {
		HAGGLE_ERR("Could not initialize forwarding manager\n");
		goto finish;
	}

	sm = new SecurityManager(kernel, securityLevel);

	if (!sm || !sm->init()) {
		HAGGLE_ERR("Could not initialize security manager\n");
		goto finish;
	}

#ifdef USE_UNIX_APPLICATION_SOCKET
	p = new ProtocolLOCAL(kernel->getStoragePath() + "/" + HAGGLE_LOCAL_SOCKET, pm);
	
	if (!p || !p->init()) {
		HAGGLE_ERR("Could not initialize LOCAL protocol\n");
		goto finish;
	}
	p->setFlag(PROT_FLAG_APPLICATION);
	p->registerWithManager();

#endif
	p = new ProtocolUDP("127.0.0.1", HAGGLE_SERVICE_DEFAULT_PORT, pm);
	/* Add ConnectivityManager last since it will start to
	* discover interfaces and generate events. At that
	* point the other managers should already be
	* running. */

	if (!p || !p->init()) {
		HAGGLE_ERR("Could not initialize UDP Application protocol\n");
		goto finish;
	}
	p->setFlag(PROT_FLAG_APPLICATION);
	p->registerWithManager();

	rm = new ResourceManager(kernel);

	if (!rm || !rm->init()) {
		HAGGLE_ERR("Could not initialize resource manager\n");
		goto finish;
	}
#ifdef BENCHMARK
	if (!isBenchmarking) {
#endif
		cm = new ConnectivityManager(kernel);

		if (!cm || !cm->init()) {
			HAGGLE_ERR("Could not initialize connectivity manager\n");
			goto finish;
		}

#ifdef BENCHMARK
	} else {
		bm = new BenchmarkManager(kernel, Benchmark_DataObjects_Attr, Benchmark_Nodes_Attr, Benchmark_Attr_Num, Benchmark_DataObjects_Num, Benchmark_Test_Num);

		if (!bm || !bm->init()) {
			HAGGLE_ERR("Could not initialize benchmark manager\n");
			goto finish;
		}
	}
#endif
#if defined(ENABLE_DEBUG_MANAGER)
	// It seems as if there can be only one accept() per
	// thread... we need to make the DebugManager register
	// protocol or something with the ProtocolTCPServer
	// somehow
	db = new DebugManager(kernel, runAsInteractive);

	if (!db || !db->init()) {
		HAGGLE_ERR("Could not initialize debug manager\n");
		/* Treat as non critical error. */
	}
#endif

	HAGGLE_DBG("Starting Haggle...\n");

#ifdef OS_WINDOWS_MOBILE
	if (platform_type(current_platform()) == platform_windows_mobile_professional)
		tray_notification_add(g_hInstance, kernel);
#endif

	kernel->run();
	retval = EXIT_SUCCESS;

	HAGGLE_DBG("Haggle finished...\n");

finish:
#ifdef BENCHMARK
	if (bm)
		delete bm;
#endif
	if (cm)
		delete cm;
	if (sm)
		delete sm;
	if (fm)
		delete fm;
	if (pm)	
		delete pm;
	if (nm)
		delete nm;
	if (dm)
		delete dm;
	if (am)
		delete am;
#if defined(ENABLE_DEBUG_MANAGER)
	if (db)
		delete db;
#endif
	if (rm)
		delete rm;

#ifdef OS_WINDOWS_MOBILE
	tray_notification_remove();
#endif
	delete kernel;
	kernel = NULL;

	return retval;
}