Example #1
0
void Call_Parser(char *filename)
{
	FILE *inFile;

	mexPrintf("\nFile name: %s\n", filename);

	inFile = fopen(filename, "r");
	if (!inFile) {
		mexPrintf("Did not find the file \"%s\".\n", filename);
		return;
	}

	Init_Symbol_Tables();
	Init_parse_util();	// initialize vars for utility functions

	yyin = inFile;
	yyparse();			// run parser
	fclose(inFile);

	Summarize();
	
	Index_All_Nodes();
	Print_Node_Table();
	Print_Device_Table();

	Init_MNA_System();
	Create_MNA_Matrix();
	Print_MNA_System();
	
}
Example #2
0
int main(int argc, char *argv[])
{
    GenericAgentConfig *config = CheckOpts(argc, argv);

    ReportContext *report_context = OpenReports("server");
    Policy *policy = GenericInitialize("server", config, report_context);
    ThisAgentInit();
    KeepPromises(policy, report_context);
    Summarize();

    StartServer(policy, config, report_context);

    ReportContextDestroy(report_context);
    GenericAgentConfigDestroy(config);
    return 0;
}
Example #3
0
int main(int argc, char *argv[])
{
    /* Ensure that if fd 0,1,2 are closed, we reserve them to avoid opening
     * the listening socket on them and closing it later when daemonising. */
    int fd = -1;
    do
    {
        fd = open(NULLFILE, O_RDWR, 0);

    } while (fd == STDIN_FILENO  ||
             fd == STDOUT_FILENO ||
             fd == STDERR_FILENO);
    close(fd);

    GenericAgentConfig *config = CheckOpts(argc, argv);
    EvalContext *ctx = EvalContextNew();
    GenericAgentConfigApply(ctx, config);

    GenericAgentDiscoverContext(ctx, config);

    Policy *policy = SelectAndLoadPolicy(config, ctx, false, false);
    
    if (!policy)
    {
        Log(LOG_LEVEL_ERR, "Error reading CFEngine policy. Exiting...");
        exit(EXIT_FAILURE);
    }

    GenericAgentPostLoadInit(ctx);
    ThisAgentInit();

    KeepPromises(ctx, policy, config);
    Summarize();

    int threads_left = StartServer(ctx, &policy, config);

    if (threads_left <= 0)
    {
        PolicyDestroy(policy);
        GenericAgentFinalize(ctx, config);
        CleanReportBookFilterSet();
    }

    return 0;
}
Example #4
0
int main(int argc, char *argv[])
{
    GenericAgentConfig *config = CheckOpts(argc, argv);

    ReportContext *report_context = OpenReports(config->agent_type);
    GenericAgentDiscoverContext(config, report_context);
    Policy *policy = GenericAgentLoadPolicy(config, report_context, false);

    CheckLicenses();

    ThisAgentInit();
    KeepPromises(policy, config, report_context);
    Summarize();

    StartServer(policy, config, report_context);

    ReportContextDestroy(report_context);
    GenericAgentConfigDestroy(config);
    return 0;
}
Example #5
0
int main(int argc, char *argv[])
{
    EvalContext *ctx = EvalContextNew();
    GenericAgentConfig *config = CheckOpts(argc, argv);
    GenericAgentConfigApply(ctx, config);

    GenericAgentDiscoverContext(ctx, config);

    Policy *policy = NULL;
    if (GenericAgentCheckPolicy(config, false))
    {
        policy = GenericAgentLoadPolicy(ctx, config);
    }
    else if (config->tty_interactive)
    {
        exit(EXIT_FAILURE);
    }
    else
    {
        Log(LOG_LEVEL_ERR, "CFEngine was not able to get confirmation of promises from cf-promises, so going to failsafe");
        EvalContextHeapAddHard(ctx, "failsafe_fallback");
        GenericAgentConfigSetInputFile(config, GetWorkDir(), "failsafe.cf");
        policy = GenericAgentLoadPolicy(ctx, config);
    }

    ThisAgentInit();
    KeepPromises(ctx, policy, config);
    Summarize();

    Log(LOG_LEVEL_NOTICE, "Server is starting...");

    StartServer(ctx, &policy, config);

    Log(LOG_LEVEL_NOTICE, "Cleaning up and exiting...");

    GenericAgentConfigDestroy(config);
    PolicyDestroy(policy);
    EvalContextDestroy(ctx);

    return 0;
}
Example #6
0
void SpectralWorker::ProcessPeriods(vector<Period> &AllPeriods, BurstsExtractor *ExtractedBursts)
{
  Buffer_t          *buffer                   = ExtractedBursts->GetBuffer();
  unsigned long long FirstEvtTime             = Get_EvTime(Buffer_GetFirstEvent(buffer));
  unsigned long long LastEvtTime              = Get_EvTime(Buffer_GetLastEvent(buffer));
  int                LevelAtPeriodZone        = Online_GetSpectralPeriodZoneLevel();
  int                LevelAtNonPeriodZone     = Online_GetSpectralNonPeriodZoneLevel();
  unsigned long long NonPeriodZoneMinDuration = Online_GetSpectralNonPeriodZoneMinDuration();
  unsigned long long PreviousPeriodZoneEnd    = 0;
  unsigned long long AutomaticBurstThreshold  = 100000;
  int                NumDetectedPeriods       = AllPeriods.size();
  Bursts            *BurstsData               = ExtractedBursts->GetBursts();
  Chopper           *Chop                     = new Chopper();

  if (FirstEvtTime < Online_GetAppResumeTime()) FirstEvtTime = Online_GetAppResumeTime();
  if (LastEvtTime  > Online_GetAppPauseTime())  LastEvtTime  = Online_GetAppPauseTime();

  /* Mask out all traced data */
  Chop->MaskAll();

  /* Compute the burst threshold that keeps the configured percentage of computations */
  if (LevelAtNonPeriodZone == BURST_MODE)
  {
    AutomaticBurstThreshold = ExtractedBursts->AdjustThreshold( Online_GetSpectralBurstThreshold() );
  }
 
  /* Process each period */
  for (int i=0; i<NumDetectedPeriods; i++)
  {
    Period *CurrentPeriod  = &(AllPeriods[i]);
    Period *PreviousPeriod = (i > 0 ? &(AllPeriods[i-1]) : NULL);
    Period *NextPeriod     = (i < NumDetectedPeriods - 1 ? &(AllPeriods[i+1]) : NULL);
    unsigned long long         PeriodZoneIni      = TIMEDESYNC(0, TASKID, CurrentPeriod->info.ini);
    unsigned long long         PeriodZoneEnd      = TIMEDESYNC(0, TASKID, CurrentPeriod->info.end);
    unsigned long long         BestItersIni       = TIMEDESYNC(0, TASKID, CurrentPeriod->info.best_ini);
    unsigned long long         BestItersEnd       = TIMEDESYNC(0, TASKID, CurrentPeriod->info.best_end);
    long long int              PeriodLength       = CurrentPeriod->info.length * 1000000; /* Nanoseconds resolution */
    int                        AllIters           = (int)(CurrentPeriod->info.iters);
    int                        DetailedIters      = (int)( (BestItersEnd - BestItersIni) / PeriodLength );
    int                        DetailedItersLeft  = DetailedIters;
    unsigned long long         CurrentTime        = 0;
    unsigned long long         CurrentTimeFitted  = 0;
    vector<unsigned long long> ItersStartingTimes;
    vector<bool>               ItersInDetail;
    unsigned long long         NonPeriodZoneStart = 0;
    unsigned long long         NonPeriodZoneEnd   = 0;
    bool                       InsideDetailedZone = false;

/* XXX */    if ((AllIters < 1) || (DetailedIters < 1)) continue;

    /* Project the starting time of each iteration from the first detailed one */
    CurrentTime = BestItersIni;
    while (CurrentTime >= PeriodZoneIni)
    {
      CurrentTime -= PeriodLength;
    }
    CurrentTime += PeriodLength; /* Now points to the start time of the first iteration in the periodic zone */

    /* Adjust the starting time of the iteration to the closest running burst starting time */
    for (int count = 0; count <= AllIters; count ++)
    {
      CurrentTimeFitted = Chop->FindCloserRunningTime(0, CurrentTime );
      ItersStartingTimes.push_back( CurrentTimeFitted );

      if ( (CurrentTime >= BestItersIni) && (DetailedItersLeft > 0) )
      {
        ItersInDetail.push_back( true );
        DetailedItersLeft --;
      }
      else
      {
        ItersInDetail.push_back( false );
      }
      CurrentTime += PeriodLength;
    }
    /*
     * vector ItersStartingTimes contains the starting time adjusted to the closest running for each iteration in the periodic zone.
     * vector ItersInDetail marks for each iteration if it has to be traced in detail or not. 
     */
 
    /* Discard the first and/or last iterations if the time adjustment exceeds the timestamps when the application was resumed/paused */
    if (ItersStartingTimes[0] < Online_GetAppResumeTime())
    {
      ItersStartingTimes.erase( ItersStartingTimes.begin() );
    }
    if (ItersStartingTimes[ ItersStartingTimes.size() - 1 ] > Online_GetAppPauseTime())
    {
      ItersStartingTimes.pop_back();
    }

    /* Now emit events marking the phases, the structure is as follows :
     *  ----------------------------------------------------------------------------------------------------------------
     *  ... ANALYSIS | NON-PERIOD | PERIOD #1 | BEST ITERS | PERIOD #1 | NON-PERIOD | PERIOD #2 | NON-PERIOD | ANALYSIS |
     *  ----------------------------------------------------------------------------------------------------------------
     *               |                                                                                       |
     *            FirstEvt                                                                                LastEvt
     */
    if (PreviousPeriod == NULL) /* First period in the current block of trace data */
    {
      if (Online_GetAppResumeTime() > 0) /* Not the first round of analysis */
      {
        /* Mark NOT TRACING from the last analysis */ 
        TRACE_ONLINE_EVENT(Online_GetAppResumeTime(), DETAIL_LEVEL_EV, NOT_TRACING);
      }
      /* NON-PERIODIC zone from the first event in the buffer until the start of the first periodic zone */
      NonPeriodZoneStart    = FirstEvtTime;
      NonPeriodZoneEnd      = ItersStartingTimes[0];
    }
    else /* Further periods in the current block of trace data */
    {
      /* NON-PERIODIC zone from the end of the previous period to the start of the current one */
      NonPeriodZoneStart    = PreviousPeriodZoneEnd;
      NonPeriodZoneEnd      = ItersStartingTimes[0];
    }
    Summarize( NonPeriodZoneStart, NonPeriodZoneEnd, NonPeriodZoneMinDuration, LevelAtNonPeriodZone, BurstsData, AutomaticBurstThreshold );

    /* PERIODIC zone */
    TRACE_ONLINE_EVENT(ItersStartingTimes[0], DETAIL_LEVEL_EV, LevelAtPeriodZone);
    for (unsigned int current_iter = 0; current_iter < ItersStartingTimes.size() - 1; current_iter ++)
    {
      if (ItersInDetail[current_iter] && !InsideDetailedZone)
      {
        InsideDetailedZone = true;
        TRACE_ONLINE_EVENT(ItersStartingTimes[current_iter], DETAIL_LEVEL_EV, DETAIL_MODE); /* Entry of detailed zone */

      }
      else if (!ItersInDetail[current_iter] && InsideDetailedZone)
      {
        InsideDetailedZone = false;
        TRACE_ONLINE_EVENT(ItersStartingTimes[current_iter], DETAIL_LEVEL_EV, LevelAtPeriodZone); /* Exit of detailed zone */
      }

      /* Emit the period ID at the start of each iteration */
      TRACE_ONLINE_EVENT(ItersStartingTimes[current_iter], PERIODICITY_EV, REPRESENTATIVE_PERIOD + CurrentPeriod->id);

      if (LevelAtPeriodZone == PHASE_PROFILE)
      {
        BurstsData->EmitPhase( ItersStartingTimes[current_iter], ItersStartingTimes[current_iter + 1], (current_iter == 0), !InsideDetailedZone );
      }
    }
  
    /* NON-PERIODIC zone after the PERIODIC zone */
    TRACE_ONLINE_EVENT(ItersStartingTimes[ ItersStartingTimes.size() - 1 ], PERIODICITY_EV, NON_PERIODIC_ZONE);
    PreviousPeriodZoneEnd = ItersStartingTimes[ ItersStartingTimes.size() - 1 ];

    if (NextPeriod == NULL)
    {
      NonPeriodZoneStart    = PreviousPeriodZoneEnd;
      NonPeriodZoneEnd      = LastEvtTime;

      Summarize( NonPeriodZoneStart, NonPeriodZoneEnd, NonPeriodZoneMinDuration, LevelAtNonPeriodZone, BurstsData, AutomaticBurstThreshold );

      TRACE_ONLINE_EVENT( NonPeriodZoneEnd, DETAIL_LEVEL_EV, NOT_TRACING );
    }

    if (CurrentPeriod->traced)
    {
      Chop->UnmaskAll( BestItersIni, BestItersEnd );
    }

    /* DEBUG -- Raw values returned by the spectral analysis 
    TRACE_ONLINE_EVENT(PeriodZoneIni, RAW_PERIODICITY_EV, REPRESENTATIVE_PERIOD + CurrentPeriod->id);
    TRACE_ONLINE_EVENT(PeriodZoneEnd, RAW_PERIODICITY_EV, 0);
    TRACE_ONLINE_EVENT(BestItersIni, RAW_BEST_ITERS_EV, REPRESENTATIVE_PERIOD + CurrentPeriod->id);
    TRACE_ONLINE_EVENT(BestItersEnd, RAW_BEST_ITERS_EV, 0); */

  }
  delete Chop;
}
static void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config)
{
    Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'",
        config->input_file);

    time_t validated_at = ReadTimestampFromPolicyValidatedFile(config, NULL);

    bool reload_config = false;

    if (config->agent_specific.daemon.last_validated_at < validated_at)
    {
        Log(LOG_LEVEL_VERBOSE, "New promises detected...");
        reload_config = true;
    }
    if (ReloadConfigRequested())
    {
        Log(LOG_LEVEL_VERBOSE, "Force reload of inputs files...");
        reload_config = true;
    }

    if (reload_config)
    {
        ClearRequestReloadConfig();

        /* Rereading policies now, so update timestamp. */
        config->agent_specific.daemon.last_validated_at = validated_at;

        if (GenericAgentArePromisesValid(config))
        {
            Log(LOG_LEVEL_NOTICE, "Rereading policy file '%s'",
                config->input_file);

            /* STEP 1: Free everything */

            EvalContextClear(ctx);

            strcpy(VDOMAIN, "undefined.domain");

            ClearAuthAndACLs();
            PolicyDestroy(*policy);               *policy = NULL;

            /* STEP 2: Set Environment, Parse and Evaluate policy */

            /*
             * TODO why is this done separately here? What's the difference to
             * calling the same steps as in cf-serverd.c:main()? Those are:
             *   GenericAgentConfigApply();     // not here!
             *   GenericAgentDiscoverContext(); // not here!
             *   EvalContextClassPutHard("server");             // only here!
             *   if (GenericAgentCheckPolicy()) // not here!
             *     policy = LoadPolicy();
             *   ThisAgentInit();               // not here, only calls umask()
             *   ReloadHAConfig();                              // only here!
             *   KeepPromises();
             *   Summarize();
             * Plus the following from within StartServer() which is only
             * called during startup:
             *   InitSignals();                  // not here
             *   ServerTLSInitialize();          // not here
             *   SetServerListenState();         // not here
             *   InitServer()                    // not here
             *   PolicyNew()+AcquireServerLock() // not here
             *   PrepareServer(sd);              // not here
             *   CollectCallStart();  // both
             */

            EvalContextSetPolicyServerFromFile(ctx, GetWorkDir());

            UpdateLastPolicyUpdateTime(ctx);

            DetectEnvironment(ctx);
            KeepHardClasses(ctx);
            LoadAugments(ctx, config);

            /* During startup this is done in GenericAgentDiscoverContext(). */
            EvalContextClassPutHard(ctx, CF_AGENTTYPES[AGENT_TYPE_SERVER], "cfe_internal,source=agent");

            time_t t = SetReferenceTime();
            UpdateTimeClasses(ctx, t);

            /* TODO BUG: this modifies config, but previous config has not
             * been reset/free'd. Ideally we would want LoadPolicy to not
             * modify config at all, but only modify ctx. */
            *policy = LoadPolicy(ctx, config);

            /* Reload HA related configuration */
            ReloadHAConfig();

            KeepPromises(ctx, *policy, config);
            Summarize();
        }
        else
        {
            Log(LOG_LEVEL_INFO, "File changes contain errors -- ignoring");
        }
    }
    else
    {
        Log(LOG_LEVEL_DEBUG, "No new promises found");
    }
}
Example #8
0
void CheckFileChanges(Policy **policy, GenericAgentConfig *config, const ReportContext *report_context)
{
    if (EnterpriseExpiry())
    {
        CfOut(cf_error, "", "!! This enterprise license is invalid.");
    }

    CfDebug("Checking file updates on %s\n", config->input_file);

    if (NewPromiseProposals(config->input_file, InputFiles(*policy)))
    {
        CfOut(cf_verbose, "", " -> New promises detected...\n");

        if (CheckPromises(config->input_file, report_context))
        {
            CfOut(cf_inform, "", "Rereading config files %s..\n", config->input_file);

            /* Free & reload -- lock this to avoid access errors during reload */

            DeleteItemList(VNEGHEAP);
            
            DeleteAlphaList(&VHEAP);
            InitAlphaList(&VHEAP);
            DeleteAlphaList(&VHARDHEAP);
            InitAlphaList(&VHARDHEAP);
            
            DeleteAlphaList(&VADDCLASSES);
            InitAlphaList(&VADDCLASSES);

            DeleteItemList(IPADDRESSES);
            IPADDRESSES = NULL;

            DeleteItemList(SV.trustkeylist);
            DeleteItemList(SV.skipverify);
            DeleteItemList(SV.attackerlist);
            DeleteItemList(SV.nonattackerlist);
            DeleteItemList(SV.multiconnlist);

            DeleteAuthList(VADMIT);
            DeleteAuthList(VDENY);

            DeleteAuthList(VARADMIT);
            DeleteAuthList(VARDENY);

            DeleteAuthList(ROLES);

            //DeleteRlist(VINPUTLIST); This is just a pointer, cannot free it

            DeleteAllScope();

            strcpy(VDOMAIN, "undefined.domain");
            POLICY_SERVER[0] = '\0';

            VADMIT = VADMITTOP = NULL;
            VDENY = VDENYTOP = NULL;

            VARADMIT = VARADMITTOP = NULL;
            VARDENY = VARDENYTOP = NULL;

            ROLES = ROLESTOP = NULL;

            VNEGHEAP = NULL;
            SV.trustkeylist = NULL;
            SV.skipverify = NULL;
            SV.attackerlist = NULL;
            SV.nonattackerlist = NULL;
            SV.multiconnlist = NULL;

            PolicyDestroy(*policy);
            *policy = NULL;

            ERRORCOUNT = 0;

            NewScope("sys");

            SetPolicyServer(POLICY_SERVER);
            NewScalar("sys", "policy_hub", POLICY_SERVER, DATA_TYPE_STRING);

            if (EnterpriseExpiry())
            {
                CfOut(cf_error, "",
                      "Cfengine - autonomous configuration engine. This enterprise license is invalid.\n");
            }

            NewScope("const");
            NewScope("this");
            NewScope("control_server");
            NewScope("control_common");
            NewScope("mon");
            NewScope("remote_access");
            GetNameInfo3();
            GetInterfacesInfo(AGENT_TYPE_SERVER);
            Get3Environment();
            BuiltinClasses();
            OSClasses();
            KeepHardClasses();

            HardClass(CF_AGENTTYPES[THIS_AGENT_TYPE]);

            SetReferenceTime(true);
            *policy = ReadPromises(AGENT_TYPE_SERVER, config, report_context);
            KeepPromises(*policy, config, report_context);
            Summarize();

        }
        else
        {
            CfOut(cf_inform, "", " !! File changes contain errors -- ignoring");
            PROMISETIME = time(NULL);
        }
    }
    else
    {
        CfDebug(" -> No new promises found\n");
    }
}
Example #9
0
void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config, time_t *last_policy_reload)
{
    time_t validated_at;

    Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'", config->input_file);

    validated_at = ReadTimestampFromPolicyValidatedMasterfiles(config);

    if (*last_policy_reload < validated_at)
    {
        *last_policy_reload = validated_at;

        Log(LOG_LEVEL_VERBOSE, "New promises detected...");

        if (GenericAgentArePromisesValid(config))
        {
            Log(LOG_LEVEL_INFO, "Rereading policy file '%s'", config->input_file);

            /* Free & reload -- lock this to avoid access errors during reload */

            EvalContextClear(ctx);

            free(SV.allowciphers);
            SV.allowciphers = NULL;

            DeleteItemList(SV.trustkeylist);
            DeleteItemList(SV.attackerlist);
            DeleteItemList(SV.nonattackerlist);
            DeleteItemList(SV.multiconnlist);

            DeleteAuthList(&SV.admit, &SV.admittail);
            DeleteAuthList(&SV.deny, &SV.denytail);

            DeleteAuthList(&SV.varadmit, &SV.varadmittail);
            DeleteAuthList(&SV.vardeny, &SV.vardenytail);

            DeleteAuthList(&SV.roles, &SV.rolestail);

            strcpy(VDOMAIN, "undefined.domain");

            SV.trustkeylist = NULL;
            SV.attackerlist = NULL;
            SV.nonattackerlist = NULL;
            SV.multiconnlist = NULL;

            acl_Free(paths_acl);    paths_acl = NULL;
            acl_Free(classes_acl);  classes_acl = NULL;
            acl_Free(vars_acl);     vars_acl = NULL;
            acl_Free(literals_acl); literals_acl = NULL;
            acl_Free(query_acl);    query_acl = NULL;

            StringMapDestroy(SV.path_shortcuts);
            SV.path_shortcuts = NULL;

            PolicyDestroy(*policy);
            *policy = NULL;

            {
                char *existing_policy_server = ReadPolicyServerFile(GetWorkDir());
                SetPolicyServer(ctx, existing_policy_server);
                free(existing_policy_server);
            }
            UpdateLastPolicyUpdateTime(ctx);

            DetectEnvironment(ctx);
            KeepHardClasses(ctx);

            EvalContextClassPutHard(ctx, CF_AGENTTYPES[AGENT_TYPE_SERVER], "cfe_internal,source=agent");

            time_t t = SetReferenceTime();
            UpdateTimeClasses(ctx, t);
            *policy = GenericAgentLoadPolicy(ctx, config);
            KeepPromises(ctx, *policy, config);
            Summarize();
        }
        else
        {
            Log(LOG_LEVEL_INFO, "File changes contain errors -- ignoring");
        }
    }
    else
    {
        Log(LOG_LEVEL_DEBUG, "No new promises found");
    }
}
int OpenReceiverChannel(void)
{
    struct addrinfo *response, *ap;
    struct addrinfo query = {
        .ai_flags = AI_PASSIVE,
        .ai_family = AF_UNSPEC,
        .ai_socktype = SOCK_STREAM
    };

    /* Listen to INADDR(6)_ANY if BINDINTERFACE unset. */
    char *ptr = NULL;
    if (BINDINTERFACE[0] != '\0')
    {
        ptr = BINDINTERFACE;
    }

    /* Resolve listening interface. */
    if (getaddrinfo(ptr, STR_CFENGINEPORT, &query, &response) != 0)
    {
        Log(LOG_LEVEL_ERR, "DNS/service lookup failure. (getaddrinfo: %s)", GetErrorStr());
        return -1;
    }

    int sd = -1;
    for (ap = response; ap != NULL; ap = ap->ai_next)
    {
        if ((sd = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol)) == -1)
        {
            continue;
        }

        int yes = 1;
        if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,
                       &yes, sizeof(yes)) == -1)
        {
            Log(LOG_LEVEL_ERR, "Socket option SO_REUSEADDR was not accepted. (setsockopt: %s)", GetErrorStr());
            exit(1);
        }

        struct linger cflinger = {
            .l_onoff = 1,
            .l_linger = 60
        };
        if (setsockopt(sd, SOL_SOCKET, SO_LINGER,
                       &cflinger, sizeof(cflinger)) == -1)
        {
            Log(LOG_LEVEL_ERR, "Socket option SO_LINGER was not accepted. (setsockopt: %s)", GetErrorStr());
            exit(1);
        }

        if (bind(sd, ap->ai_addr, ap->ai_addrlen) != -1)
        {
            if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG)
            {
                /* Convert IP address to string, no DNS lookup performed. */
                char txtaddr[CF_MAX_IP_LEN] = "";
                getnameinfo(ap->ai_addr, ap->ai_addrlen,
                            txtaddr, sizeof(txtaddr),
                            NULL, 0, NI_NUMERICHOST);
                Log(LOG_LEVEL_DEBUG, "Bound to address '%s' on '%s' = %d", txtaddr,
                    CLASSTEXT[VSYSTEMHARDCLASS], VSYSTEMHARDCLASS);
            }
            break;
        }
        else
        {
            Log(LOG_LEVEL_ERR, "Could not bind server address. (bind: %s)", GetErrorStr());
            cf_closesocket(sd);
        }
    }

    if (sd < 0)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open/bind a socket");
        exit(1);
    }

    freeaddrinfo(response);
    return sd;
}

/*********************************************************************/
/* Level 3                                                           */
/*********************************************************************/

void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config)
{
    Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'", config->input_file);

    if (NewPromiseProposals(ctx, config, InputFiles(ctx, *policy)))
    {
        Log(LOG_LEVEL_VERBOSE, "New promises detected...");

        if (CheckPromises(config))
        {
            Log(LOG_LEVEL_INFO, "Rereading policy file '%s'", config->input_file);

            /* Free & reload -- lock this to avoid access errors during reload */
            
            EvalContextHeapClear(ctx);

            DeleteItemList(IPADDRESSES);
            IPADDRESSES = NULL;

            DeleteItemList(SV.trustkeylist);
            DeleteItemList(SV.skipverify);
            DeleteItemList(SV.attackerlist);
            DeleteItemList(SV.nonattackerlist);
            DeleteItemList(SV.multiconnlist);

            DeleteAuthList(SV.admit);
            DeleteAuthList(SV.deny);

            DeleteAuthList(SV.varadmit);
            DeleteAuthList(SV.vardeny);

            DeleteAuthList(SV.roles);

            //DeleteRlist(VINPUTLIST); This is just a pointer, cannot free it

            ScopeDeleteAll();

            strcpy(VDOMAIN, "undefined.domain");
            POLICY_SERVER[0] = '\0';

            SV.admit = NULL;
            SV.admittop = NULL;

            SV.varadmit = NULL;
            SV.varadmittop = NULL;

            SV.deny = NULL;
            SV.denytop = NULL;

            SV.vardeny = NULL;
            SV.vardenytop = NULL;

            SV.roles = NULL;
            SV.rolestop = NULL;

            SV.trustkeylist = NULL;
            SV.skipverify = NULL;
            SV.attackerlist = NULL;
            SV.nonattackerlist = NULL;
            SV.multiconnlist = NULL;

            PolicyDestroy(*policy);
            *policy = NULL;

            {
                char *existing_policy_server = ReadPolicyServerFile(GetWorkDir());
                SetPolicyServer(ctx, existing_policy_server);
                free(existing_policy_server);
            }

            GetNameInfo3(ctx, AGENT_TYPE_SERVER);
            GetInterfacesInfo(ctx, AGENT_TYPE_SERVER);
            Get3Environment(ctx, AGENT_TYPE_SERVER);
            BuiltinClasses(ctx);
            OSClasses(ctx);
            KeepHardClasses(ctx);

            EvalContextHeapAddHard(ctx, CF_AGENTTYPES[config->agent_type]);

            SetReferenceTime(ctx, true);
            *policy = GenericAgentLoadPolicy(ctx, config);
            KeepPromises(ctx, *policy, config);
            Summarize();

        }
        else
        {
            Log(LOG_LEVEL_INFO, "File changes contain errors -- ignoring");
            PROMISETIME = time(NULL);
        }
    }
    else
    {
        Log(LOG_LEVEL_DEBUG, "No new promises found");
    }
}
Example #11
0
const TypeMatcher::Result TypeMatcher::Match(std::list<MatchCandidateEntry> candidates, std::vector<Type> input_signature) const{
    // Currently the matcher does a first fit search, and it ignores possible implicit conversions.

    // Generate possible conversions for each input type
    std::vector<std::list<Conversion>> inflated = InflateTypes(input_signature);
    // Generate all combinations of conversions
    std::list<std::vector<Conversion>> combinations = CombinationWalker(inflated);
    // Filter out those that match some operator
    combinations.remove_if(
        [&](const std::vector<Conversion> v){
            // Search for a matching OperatorEntry. This is not O(1)! It could
            // be if operator_variants was a map instead of a list... but then
            // the BinOpCreator would be a
            //   map(string -> map( (type,type) -> (type,function) )
            // and that seems just mad. We might use that approach once there is A LOT of possible conversions.
            for(const MatchCandidateEntry& mce : candidates){
                // Check if all targets match.
                if(TestCandidateMatch(mce, v)){
                    // Match! Do not remove this conversion combination
                    return false;
                }
            }
            // No match found. Remove this combination.
            return true;
        }
    );
    // If no combinations remain, fail.
    if(combinations.size() == 0)
        return Result(Result::NONE);

    // Summarize conversion costs for each combination
    std::list<std::pair<ConversionCost, std::vector<Conversion>>> combinations_with_total_costs;
    for(const std::vector<Conversion> v : combinations)
        combinations_with_total_costs.push_back({ Summarize(v), v});
    // Find the minimal cost
    ConversionCost minimum = combinations_with_total_costs.front().first;
    for(const auto& p : combinations_with_total_costs)
        if(p.first < minimum)
            minimum = p.first;
    // Filter out combinations that have non-optimal cost
    combinations_with_total_costs.remove_if([&](auto p){
            return p.first != minimum;
        });
    // At this point, exactly one match should be left.
    if(combinations_with_total_costs.size() == 0){
        ctx.AddError("Internal error: the above operations should not have emptied the combination list.");
        return Result(Result::NONE);
    }else if(combinations_with_total_costs.size() > 1){
        //TODO: Somehow embed the information about viable candidates in the result returned
        return Result(Result::MULTIPLE);
    }
    // We have confirmed that there is indeed just one match. Let's unwrap it:
    std::vector<Conversion> best_match = combinations_with_total_costs.front().second;
    // Now find the candidate for this match.
    for(const MatchCandidateEntry& mce : candidates){
        if(!TestCandidateMatch(mce, best_match)) continue;

        // At this point, oe is the matching operator variant.
        // Finally, we can prepare the application function.
        Result::ConverterFunctions cfcs;
        for(size_t i = 0; i < best_match.size(); i++) {
            cfcs.push_back(
                [best_match, i](llvm::Value* v) -> llvm::Value* {
                    return best_match[i].converter(v);
                }
            );
        }
        return Result(Result::UNIQUE, mce, cfcs);
    }
    
    ctx.AddError("Internal error: Match was found, but it has no corresponding operator variant.");
    return Result(Result::NONE);
}
int OpenReceiverChannel(void)
{
    struct addrinfo *response, *ap;
    struct addrinfo query = {
        .ai_flags = AI_PASSIVE,
        .ai_family = AF_UNSPEC,
        .ai_socktype = SOCK_STREAM
    };

    /* Listen to INADDR(6)_ANY if BINDINTERFACE unset. */
    char *ptr = NULL;
    if (BINDINTERFACE[0] != '\0')
    {
        ptr = BINDINTERFACE;
    }

    char servname[10];
    snprintf(servname, 10, "%d", CFENGINE_PORT);

    /* Resolve listening interface. */
    if (getaddrinfo(ptr, servname, &query, &response) != 0)
    {
        Log(LOG_LEVEL_ERR, "DNS/service lookup failure. (getaddrinfo: %s)", GetErrorStr());
        return -1;
    }

    int sd = -1;
    for (ap = response; ap != NULL; ap = ap->ai_next)
    {
        if ((sd = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol)) == -1)
        {
            continue;
        }

        int yes = 1;
        if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,
                       &yes, sizeof(yes)) == -1)
        {
            Log(LOG_LEVEL_ERR, "Socket option SO_REUSEADDR was not accepted. (setsockopt: %s)", GetErrorStr());
            exit(1);
        }

        struct linger cflinger = {
            .l_onoff = 1,
            .l_linger = 60
        };
        if (setsockopt(sd, SOL_SOCKET, SO_LINGER,
                       &cflinger, sizeof(cflinger)) == -1)
        {
            Log(LOG_LEVEL_ERR, "Socket option SO_LINGER was not accepted. (setsockopt: %s)", GetErrorStr());
            exit(1);
        }

        if (bind(sd, ap->ai_addr, ap->ai_addrlen) != -1)
        {
            if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG)
            {
                /* Convert IP address to string, no DNS lookup performed. */
                char txtaddr[CF_MAX_IP_LEN] = "";
                getnameinfo(ap->ai_addr, ap->ai_addrlen,
                            txtaddr, sizeof(txtaddr),
                            NULL, 0, NI_NUMERICHOST);
                Log(LOG_LEVEL_DEBUG, "Bound to address '%s' on '%s' = %d", txtaddr,
                    CLASSTEXT[VSYSTEMHARDCLASS], VSYSTEMHARDCLASS);
            }
            break;
        }
        else
        {
            Log(LOG_LEVEL_ERR, "Could not bind server address. (bind: %s)", GetErrorStr());
            cf_closesocket(sd);
        }
    }

    if (sd < 0)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open/bind a socket");
        exit(1);
    }

    freeaddrinfo(response);
    return sd;
}

/*********************************************************************/
/* Level 3                                                           */
/*********************************************************************/

void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config, time_t *last_policy_reload)
{
    time_t validated_at;

    Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'", config->input_file);

    validated_at = ReadTimestampFromPolicyValidatedMasterfiles(config);

    if (*last_policy_reload < validated_at)
    {
        *last_policy_reload = validated_at;

        Log(LOG_LEVEL_VERBOSE, "New promises detected...");

        if (GenericAgentArePromisesValid(config))
        {
            Log(LOG_LEVEL_INFO, "Rereading policy file '%s'", config->input_file);

            /* Free & reload -- lock this to avoid access errors during reload */
            
            EvalContextClear(ctx);

            free(SV.allowciphers);
            SV.allowciphers = NULL;

            DeleteItemList(SV.trustkeylist);
            DeleteItemList(SV.attackerlist);
            DeleteItemList(SV.nonattackerlist);
            DeleteItemList(SV.multiconnlist);

            DeleteAuthList(SV.admit);
            DeleteAuthList(SV.deny);

            DeleteAuthList(SV.varadmit);
            DeleteAuthList(SV.vardeny);

            DeleteAuthList(SV.roles);

            strcpy(VDOMAIN, "undefined.domain");

            SV.admit = NULL;
            SV.admittop = NULL;

            SV.varadmit = NULL;
            SV.varadmittop = NULL;

            SV.deny = NULL;
            SV.denytop = NULL;

            SV.vardeny = NULL;
            SV.vardenytop = NULL;

            SV.roles = NULL;
            SV.rolestop = NULL;

            SV.trustkeylist = NULL;
            SV.attackerlist = NULL;
            SV.nonattackerlist = NULL;
            SV.multiconnlist = NULL;

            PolicyDestroy(*policy);
            *policy = NULL;

            {
                char *existing_policy_server = ReadPolicyServerFile(GetWorkDir());
                SetPolicyServer(ctx, existing_policy_server);
                free(existing_policy_server);
            }
            UpdateLastPolicyUpdateTime(ctx);

            DetectEnvironment(ctx);
            KeepHardClasses(ctx);

            EvalContextClassPutHard(ctx, CF_AGENTTYPES[config->agent_type], "cfe_internal,source=agent");

            time_t t = SetReferenceTime();
            UpdateTimeClasses(ctx, t);
            *policy = GenericAgentLoadPolicy(ctx, config);
            KeepPromises(ctx, *policy, config);
            Summarize();
        }
        else
        {
            Log(LOG_LEVEL_INFO, "File changes contain errors -- ignoring");
        }
    }
    else
    {
        Log(LOG_LEVEL_DEBUG, "No new promises found");
    }
}