示例#1
0
文件: cf-runagent.c 项目: kacf/core
static int HailServer(const EvalContext *ctx, const GenericAgentConfig *config,
                      char *host)
{
    assert(host != NULL);

    AgentConnection *conn;
    char hostkey[CF_HOSTKEY_STRING_SIZE], user[CF_SMALLBUF];
    bool gotkey;
    char reply[8];
    bool trustkey = false;

    char *hostname, *port;
    ParseHostPort(host, &hostname, &port);

    if (hostname == NULL)
    {
        Log(LOG_LEVEL_INFO, "No remote hosts were specified to connect to");
        return false;
    }
    if (port == NULL)
    {
        port = "5308";
    }

    char ipaddr[CF_MAX_IP_LEN];
    if (Hostname2IPString(ipaddr, hostname, sizeof(ipaddr)) == -1)
    {
        Log(LOG_LEVEL_ERR,
            "HailServer: ERROR, could not resolve '%s'", hostname);
        return false;
    }

    Address2Hostkey(hostkey, sizeof(hostkey), ipaddr);
    GetCurrentUserName(user, sizeof(user));

    if (INTERACTIVE)
    {
        Log(LOG_LEVEL_VERBOSE, "Using interactive key trust...");

        gotkey = HavePublicKey(user, ipaddr, hostkey) != NULL;
        if (!gotkey)
        {
            /* TODO print the hash of the connecting host. But to do that we
             * should open the connection first, and somehow pass that hash
             * here! redmine#7212 */
            printf("WARNING - You do not have a public key from host %s = %s\n",
                   hostname, ipaddr);
            printf("          Do you want to accept one on trust? (yes/no)\n\n--> ");

            while (true)
            {
                if (fgets(reply, sizeof(reply), stdin) == NULL)
                {
                    FatalError(ctx, "EOF trying to read answer from terminal");
                }

                if (Chop(reply, CF_EXPANDSIZE) == -1)
                {
                    Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator");
                }

                if (strcmp(reply, "yes") == 0)
                {
                    printf("Will trust the key...\n");
                    trustkey = true;
                    break;
                }
                else if (strcmp(reply, "no") == 0)
                {
                    printf("Will not trust the key...\n");
                    trustkey = false;
                    break;
                }
                else
                {
                    printf("Please reply yes or no...(%s)\n", reply);
                }
            }
        }
    }


#ifndef __MINGW32__
    if (BACKGROUND)
    {
        Log(LOG_LEVEL_INFO, "Hailing %s : %s (in the background)",
            hostname, port);
    }
    else
#endif
    {
        Log(LOG_LEVEL_INFO,
            "........................................................................");
        Log(LOG_LEVEL_INFO, "Hailing %s : %s",
            hostname, port);
        Log(LOG_LEVEL_INFO,
            "........................................................................");
    }

    ConnectionFlags connflags = {
        .protocol_version = config->protocol_version,
        .trust_server = trustkey
    };
    int err = 0;
    conn = ServerConnection(hostname, port, CONNTIMEOUT, connflags, &err);

    if (conn == NULL)
    {
        Log(LOG_LEVEL_ERR, "Failed to connect to host: %s", hostname);
        return false;
    }

    /* Send EXEC command. */
    HailExec(conn, hostname);

    return true;
}

/********************************************************************/
/* Level 2                                                          */
/********************************************************************/

static void KeepControlPromises(EvalContext *ctx, const Policy *policy)
{
    Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_RUNAGENT);
    if (constraints)
    {
        for (size_t i = 0; i < SeqLength(constraints); i++)
        {
            Constraint *cp = SeqAt(constraints, i);

            if (!IsDefinedClass(ctx, cp->classes))
            {
                continue;
            }

            VarRef *ref = VarRefParseFromScope(cp->lval, "control_runagent");
            DataType value_type;
            const void *value = EvalContextVariableGet(ctx, ref, &value_type);
            VarRefDestroy(ref);

            /* If var not found, or if it's an empty list. */
            if (value_type == CF_DATA_TYPE_NONE || value == NULL)
            {
                Log(LOG_LEVEL_ERR, "Unknown lval '%s' in runagent control body", cp->lval);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_FORCE_IPV4].lval) == 0)
            {
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_TRUSTKEY].lval) == 0)
            {
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_ENCRYPT].lval) == 0)
            {
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_PORT_NUMBER].lval) == 0)
            {
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_BACKGROUND].lval) == 0)
            {
                /*
                 * Only process this option if are is no -b or -i options specified on
                 * command line.
                 */
                if (BACKGROUND || INTERACTIVE)
                {
                    Log(LOG_LEVEL_WARNING,
                        "'background_children' setting from 'body runagent control' is overridden by command-line option.");
                }
                else
                {
                    BACKGROUND = BooleanFromString(value);
                }
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_MAX_CHILD].lval) == 0)
            {
                MAXCHILD = (short) IntFromString(value);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_OUTPUT_TO_FILE].lval) == 0)
            {
                OUTPUT_TO_FILE = BooleanFromString(value);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_OUTPUT_DIRECTORY].lval) == 0)
            {
                if (IsAbsPath(value))
                {
                    strlcpy(OUTPUT_DIRECTORY, value, CF_BUFSIZE);
                    Log(LOG_LEVEL_VERBOSE, "Setting output direcory to '%s'", OUTPUT_DIRECTORY);
                }
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_TIMEOUT].lval) == 0)
            {
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_HOSTS].lval) == 0)
            {
                if (HOSTLIST == NULL)       // Don't override if command line setting
                {
                    HOSTLIST = value;
                }

                continue;
            }
        }
    }

    const char *expire_after = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_LASTSEEN_EXPIRE_AFTER);
    if (expire_after)
    {
        LASTSEENEXPIREAFTER = IntFromString(expire_after) * 60;
    }

}
示例#2
0
文件: syntax.c 项目: embedian/core
DataType StringDataType(EvalContext *ctx, const char *string)
{
    int islist = false;
    DataType dtype = DATA_TYPE_NONE;

/*-------------------------------------------------------
What happens if we embed vars in a literal string
       "$(list)withending" - a list?
       "$(list1)$(list2)"  - not a simple list
Disallow these manual concatenations as ambiguous.
Demand this syntax to work around

vars:

   "listvar" slist => EmbellishList("prefix$(list)suffix");
---------------------------------------------------------*/

    size_t len = strlen(string);

    if (*string == '$')
    {
        Buffer *inner_value = BufferNew();
        if (ExtractScalarReference(inner_value, string, len, true))
        {
            if (!IsExpandable(BufferData(inner_value)))
            {
                VarRef *ref = VarRefParse(BufferData(inner_value));
                if (EvalContextVariableGet(ctx, ref, &dtype))
                {
                    if (DataTypeToRvalType(dtype) == RVAL_TYPE_LIST)
                    {
                        if (!islist)
                        {
                            islist = true;
                        }
                        else
                        {
                            islist = false;
                        }
                    }
                }

                VarRefDestroy(ref);
            }

            if (BufferSize(inner_value) == strlen(string))
            {
                BufferDestroy(inner_value);
                return dtype;
            }
            else
            {
                BufferDestroy(inner_value);
                return DATA_TYPE_STRING;
            }
        }

        BufferDestroy(inner_value);
    }

    return DATA_TYPE_STRING;
}
示例#3
0
void ExecConfigUpdate(const EvalContext *ctx, const Policy *policy, ExecConfig *exec_config)
{
    ExecConfigResetDefault(exec_config);

    Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_EXECUTOR);
    if (constraints)
    {
        for (size_t i = 0; i < SeqLength(constraints); i++)
        {
            Constraint *cp = SeqAt(constraints, i);

            if (!IsDefinedClass(ctx, cp->classes, NULL))
            {
                continue;
            }

            Rval retval;
            if (!EvalContextVariableGet(ctx, (VarRef) { NULL, "control_executor", cp->lval }, &retval, NULL))
            {
                // TODO: should've been checked before this point. change to programming error
                CfOut(OUTPUT_LEVEL_ERROR, "", "Unknown lval %s in exec control body", cp->lval);
                continue;
            }

            if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILFROM].lval) == 0)
            {
                free(exec_config->mail_from_address);
                exec_config->mail_from_address = xstrdup(retval.item);
                CfDebug("mailfrom = %s\n", exec_config->mail_from_address);
            }
            else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILTO].lval) == 0)
            {
                free(exec_config->mail_to_address);
                exec_config->mail_to_address = xstrdup(retval.item);
                CfDebug("mailto = %s\n", exec_config->mail_to_address);
            }
            else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_SMTPSERVER].lval) == 0)
            {
                free(exec_config->mail_server);
                exec_config->mail_server = xstrdup(retval.item);
                CfDebug("smtpserver = %s\n", exec_config->mail_server);
            }
            else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_EXECCOMMAND].lval) == 0)
            {
                free(exec_config->exec_command);
                exec_config->exec_command = xstrdup(retval.item);
                CfDebug("exec_command = %s\n", exec_config->exec_command);
            }
            else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_AGENT_EXPIREAFTER].lval) == 0)
            {
                exec_config->agent_expireafter = IntFromString(retval.item);
                CfDebug("agent_expireafter = %d\n", exec_config->agent_expireafter);
            }
            else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_EXECUTORFACILITY].lval) == 0)
            {
                exec_config->log_facility = xstrdup(retval.item);
                CfDebug("executorfacility = %s\n", exec_config->log_facility);
            }
            else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILMAXLINES].lval) == 0)
            {
                exec_config->mail_max_lines = IntFromString(retval.item);
                CfDebug("maxlines = %d\n", exec_config->mail_max_lines);
            }
            else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_SPLAYTIME].lval) == 0)
            {
                int time = IntFromString(RvalScalarValue(retval));
                exec_config->splay_time = (int) (time * SECONDS_PER_MINUTE * GetSplay());
            }
            else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_SCHEDULE].lval) == 0)
            {
                CfDebug("Loading user-defined schedule...\n");
                StringSetClear(exec_config->schedule);

                for (const Rlist *rp = retval.item; rp; rp = rp->next)
                {
                    StringSetAdd(exec_config->schedule, xstrdup(RlistScalarValue(rp)));
                    CfDebug("Adding %s\n", RlistScalarValue(rp));
                }
            }
        }
    }
}
示例#4
0
void VerifyVarPromise(EvalContext *ctx, const Promise *pp, bool allow_duplicates)
{
    ConvergeVariableOptions opts = CollectConvergeVariableOptions(ctx, pp, allow_duplicates);
    if (!opts.should_converge)
    {
        return;
    }

    char *scope = NULL;
    if (strcmp("meta", pp->parent_promise_type->name) == 0)
    {
        scope = StringConcatenate(2, PromiseGetBundle(pp)->name, "_meta");
    }
    else
    {
        scope = xstrdup(PromiseGetBundle(pp)->name);
    }

    //More consideration needs to be given to using these
    //a.transaction = GetTransactionConstraints(pp);
    Attributes a = { {0} };
    a.classes = GetClassDefinitionConstraints(ctx, pp);

    Rval existing_var_rval;
    DataType existing_var_type = DATA_TYPE_NONE;
    EvalContextVariableGet(ctx, (VarRef) { NULL, scope, pp->promiser }, &existing_var_rval, &existing_var_type);
    Buffer *qualified_scope = BufferNew();
    int result = 0;
    if (strcmp(PromiseGetNamespace(pp), "default") == 0)
    {
        result = BufferSet(qualified_scope, scope, strlen(scope));
        if (result < 0)
        {
            /*
             * Even though there will be no problems with memory allocation, there
             * might be other problems.
             */
            UnexpectedError("Problems writing to buffer");
            free(scope);
            BufferDestroy(&qualified_scope);
            return;
        }
    }
    else
    {
        if (strchr(scope, ':') == NULL)
        {
            result = BufferPrintf(qualified_scope, "%s:%s", PromiseGetNamespace(pp), scope);
            if (result < 0)
            {
                /*
                 * Even though there will be no problems with memory allocation, there
                 * might be other problems.
                 */
                UnexpectedError("Problems writing to buffer");
                free(scope);
                BufferDestroy(&qualified_scope);
                return;
            }
        }
        else
        {
            result = BufferSet(qualified_scope, scope, strlen(scope));
            if (result < 0)
            {
                /*
                 * Even though there will be no problems with memory allocation, there
                 * might be other problems.
                 */
                UnexpectedError("Problems writing to buffer");
                free(scope);
                BufferDestroy(&qualified_scope);
                return;
            }
        }
    }

    PromiseResult promise_result;

    Rval rval = opts.cp_save->rval;

    if (rval.item != NULL)
    {
        FnCall *fp = (FnCall *) rval.item;

        if (opts.cp_save->rval.type == RVAL_TYPE_FNCALL)
        {
            if (existing_var_type != DATA_TYPE_NONE)
            {
                // Already did this
                free(scope);
                BufferDestroy(&qualified_scope);
                return;
            }

            FnCallResult res = FnCallEvaluate(ctx, fp, pp);

            if (res.status == FNCALL_FAILURE)
            {
                /* We do not assign variables to failed fn calls */
                RvalDestroy(res.rval);
                free(scope);
                BufferDestroy(&qualified_scope);
                return;
            }
            else
            {
                rval = res.rval;
            }
        }
        else
        {
            Buffer *conv = BufferNew();

            if (strcmp(opts.cp_save->lval, "int") == 0)
            {
                result = BufferPrintf(conv, "%ld", IntFromString(opts.cp_save->rval.item));
                if (result < 0)
                {
                    /*
                     * Even though there will be no problems with memory allocation, there
                     * might be other problems.
                     */
                    UnexpectedError("Problems writing to buffer");
                    free(scope);
                    BufferDestroy(&qualified_scope);
                    BufferDestroy(&conv);
                    return;
                }
                rval = RvalCopy((Rval) {(char *)BufferData(conv), opts.cp_save->rval.type});
            }
            else if (strcmp(opts.cp_save->lval, "real") == 0)
            {
                double real_value = 0.0;
                if (DoubleFromString(opts.cp_save->rval.item, &real_value))
                {
                    result = BufferPrintf(conv, "%lf", real_value);
                }
                else
                {
                    result = BufferPrintf(conv, "(double conversion error)");
                }

                if (result < 0)
                {
                    /*
                     * Even though there will be no problems with memory allocation, there
                     * might be other problems.
                     */
                    UnexpectedError("Problems writing to buffer");
                    free(scope);
                    BufferDestroy(&conv);
                    BufferDestroy(&qualified_scope);
                    return;
                }
                rval = RvalCopy((Rval) {(char *)BufferData(conv), opts.cp_save->rval.type});
            }
            else
            {
                rval = RvalCopy(opts.cp_save->rval);
            }

            if (rval.type == RVAL_TYPE_LIST)
            {
                Rlist *rval_list = RvalRlistValue(rval);
                RlistFlatten(ctx, &rval_list);
                rval.item = rval_list;
            }

            BufferDestroy(&conv);
        }

        if (Epimenides(ctx, PromiseGetBundle(pp)->name, pp->promiser, rval, 0))
        {
            CfOut(OUTPUT_LEVEL_ERROR, "", "Variable \"%s\" contains itself indirectly - an unkeepable promise", pp->promiser);
            exit(1);
        }
        else
        {
            /* See if the variable needs recursively expanding again */

            Rval returnval = EvaluateFinalRval(ctx, BufferData(qualified_scope), rval, true, pp);

            RvalDestroy(rval);

            // freed before function exit
            rval = returnval;
        }

        if (existing_var_type != DATA_TYPE_NONE)
        {
            if (opts.ok_redefine)    /* only on second iteration, else we ignore broken promises */
            {
                ScopeDeleteVariable(BufferData(qualified_scope), pp->promiser);
            }
            else if ((THIS_AGENT_TYPE == AGENT_TYPE_COMMON) && (CompareRval(existing_var_rval, rval) == false))
            {
                switch (rval.type)
                {
                case RVAL_TYPE_SCALAR:
                    CfOut(OUTPUT_LEVEL_VERBOSE, "", " !! Redefinition of a constant scalar \"%s\" (was %s now %s)",
                          pp->promiser, RvalScalarValue(existing_var_rval), RvalScalarValue(rval));
                    PromiseRef(OUTPUT_LEVEL_VERBOSE, pp);
                    break;

                case RVAL_TYPE_LIST:
                    {
                        CfOut(OUTPUT_LEVEL_VERBOSE, "", " !! Redefinition of a constant list \"%s\".", pp->promiser);
                        Writer *w = StringWriter();
                        RlistWrite(w, existing_var_rval.item);
                        char *oldstr = StringWriterClose(w);
                        CfOut(OUTPUT_LEVEL_VERBOSE, "", "Old value: %s", oldstr);
                        free(oldstr);

                        w = StringWriter();
                        RlistWrite(w, rval.item);
                        char *newstr = StringWriterClose(w);
                        CfOut(OUTPUT_LEVEL_VERBOSE, "", " New value: %s", newstr);
                        free(newstr);
                        PromiseRef(OUTPUT_LEVEL_VERBOSE, pp);
                    }
                    break;

                default:
                    break;
                }
            }
        }

        if (IsCf3VarString(pp->promiser))
        {
            // Unexpanded variables, we don't do anything with
            RvalDestroy(rval);
            free(scope);
            BufferDestroy(&qualified_scope);
            return;
        }

        if (!FullTextMatch("[a-zA-Z0-9_\200-\377.]+(\\[.+\\])*", pp->promiser))
        {
            CfOut(OUTPUT_LEVEL_ERROR, "", " !! Variable identifier contains illegal characters");
            PromiseRef(OUTPUT_LEVEL_ERROR, pp);
            RvalDestroy(rval);
            free(scope);
            BufferDestroy(&qualified_scope);
            return;
        }

        if (opts.drop_undefined && rval.type == RVAL_TYPE_LIST)
        {
            for (Rlist *rp = rval.item; rp != NULL; rp = rp->next)
            {
                if (IsNakedVar(rp->item, '@'))
                {
                    free(rp->item);
                    rp->item = xstrdup(CF_NULL_VALUE);
                }
            }
        }

        if (!EvalContextVariablePut(ctx, (VarRef) { NULL, BufferData(qualified_scope), pp->promiser }, rval, DataTypeFromString(opts.cp_save->lval)))
        {
            CfOut(OUTPUT_LEVEL_VERBOSE, "", "Unable to converge %s.%s value (possibly empty or infinite regression)\n", BufferData(qualified_scope), pp->promiser);
            PromiseRef(OUTPUT_LEVEL_VERBOSE, pp);
            promise_result = PROMISE_RESULT_FAIL;
        }
        else
        {
            promise_result = PROMISE_RESULT_CHANGE;
        }
    }
    else
    {
        CfOut(OUTPUT_LEVEL_ERROR, "", " !! Variable %s has no promised value\n", pp->promiser);
        CfOut(OUTPUT_LEVEL_ERROR, "", " !! Rule from %s at/before line %zu\n", PromiseGetBundle(pp)->source_path, opts.cp_save->offset.line);
        promise_result = PROMISE_RESULT_FAIL;
    }

    /*
     * FIXME: Variable promise are exempt from normal evaluation logic still, so
     * they are not pushed to evaluation stack before being evaluated. Due to
     * this reason, we cannot call cfPS here to set classes, as it will error
     * out with ProgrammingError.
     *
     * In order to support 'classes' body for variables as well, we call
     * ClassAuditLog explicitly.
     */
    ClassAuditLog(ctx, pp, a, promise_result);

    free(scope);
    BufferDestroy(&qualified_scope);
    RvalDestroy(rval);
}
示例#5
0
static int HailServer(EvalContext *ctx, char *host)
{
    AgentConnection *conn;
    char sendbuffer[CF_BUFSIZE], recvbuffer[CF_BUFSIZE], peer[CF_MAXVARSIZE],
        digest[CF_MAXVARSIZE], user[CF_SMALLBUF];
    bool gotkey;
    char reply[8];

    FileCopy fc = {
        .portnumber = (unsigned short) ParseHostname(host, peer),
    };

    char ipaddr[CF_MAX_IP_LEN];
    if (Hostname2IPString(ipaddr, peer, sizeof(ipaddr)) == -1)
    {
        Log(LOG_LEVEL_ERR,
            "HailServer: ERROR, could not resolve '%s'", peer);
        return false;
    }

    Address2Hostkey(ipaddr, digest);
    GetCurrentUserName(user, CF_SMALLBUF);

    if (INTERACTIVE)
    {
        Log(LOG_LEVEL_VERBOSE, "Using interactive key trust...");

        gotkey = HavePublicKey(user, peer, digest) != NULL;

        if (!gotkey)
        {
            gotkey = HavePublicKey(user, ipaddr, digest) != NULL;
        }

        if (!gotkey)
        {
            printf("WARNING - You do not have a public key from host %s = %s\n",
                   host, ipaddr);
            printf("          Do you want to accept one on trust? (yes/no)\n\n--> ");

            while (true)
            {
                if (fgets(reply, sizeof(reply), stdin) == NULL)
                {
                    FatalError(ctx, "EOF trying to read answer from terminal");
                }

                if (Chop(reply, CF_EXPANDSIZE) == -1)
                {
                    Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator");
                }

                if (strcmp(reply, "yes") == 0)
                {
                    printf("Will trust the key...\n");
                    fc.trustkey = true;
                    break;
                }
                else if (strcmp(reply, "no") == 0)
                {
                    printf("Will not trust the key...\n");
                    fc.trustkey = false;
                    break;
                }
                else
                {
                    printf("Please reply yes or no...(%s)\n", reply);
                }
            }
        }
    }

/* Continue */

#ifdef __MINGW32__

    if (LEGACY_OUTPUT)
    {
        Log(LOG_LEVEL_INFO, "...........................................................................");
        Log(LOG_LEVEL_INFO, " * Hailing %s : %u, with options \"%s\" (serial)", peer, fc.portnumber,
              REMOTE_AGENT_OPTIONS);
        Log(LOG_LEVEL_INFO, "...........................................................................");
    }
    else
    {
        Log(LOG_LEVEL_INFO, "Hailing '%s' : %u, with options '%s' (serial)", peer, fc.portnumber,
            REMOTE_AGENT_OPTIONS);
    }


#else /* !__MINGW32__ */

    if (BACKGROUND)
    {
        Log(LOG_LEVEL_INFO, "Hailing '%s' : %u, with options '%s' (parallel)", peer, fc.portnumber,
              REMOTE_AGENT_OPTIONS);
    }
    else
    {
        if (LEGACY_OUTPUT)
        {
            Log(LOG_LEVEL_INFO, "...........................................................................");
            Log(LOG_LEVEL_INFO, " * Hailing %s : %u, with options \"%s\" (serial)", peer, fc.portnumber,
                  REMOTE_AGENT_OPTIONS);
            Log(LOG_LEVEL_INFO, "...........................................................................");
        }
        else
        {
            Log(LOG_LEVEL_INFO, "Hailing '%s' : %u, with options '%s' (serial)", peer, fc.portnumber,
                  REMOTE_AGENT_OPTIONS);
        }
    }

#endif /* !__MINGW32__ */

    fc.servers = RlistFromSplitString(peer, '*');

    if (fc.servers == NULL || strcmp(fc.servers->item, "localhost") == 0)
    {
        Log(LOG_LEVEL_INFO, "No hosts are registered to connect to");
        return false;
    }
    else
    {
        int err = 0;
        conn = NewServerConnection(fc, false, &err);

        if (conn == NULL)
        {
            RlistDestroy(fc.servers);
            Log(LOG_LEVEL_VERBOSE, "No suitable server responded to hail");
            return false;
        }
    }

/* Check trust interaction*/

    HailExec(conn, peer, recvbuffer, sendbuffer);

    RlistDestroy(fc.servers);

    return true;
}

/********************************************************************/
/* Level 2                                                          */
/********************************************************************/

static void KeepControlPromises(EvalContext *ctx, Policy *policy)
{
    Rval retval;

    RUNATTR.copy.trustkey = false;
    RUNATTR.copy.encrypt = true;
    RUNATTR.copy.force_ipv4 = false;
    RUNATTR.copy.portnumber = SHORT_CFENGINEPORT;

/* Keep promised agent behaviour - control bodies */

    Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_RUNAGENT);
    if (constraints)
    {
        for (size_t i = 0; i < SeqLength(constraints); i++)
        {
            Constraint *cp = SeqAt(constraints, i);

            if (!IsDefinedClass(ctx, cp->classes, NULL))
            {
                continue;
            }

            VarRef *ref = VarRefParseFromScope(cp->lval, "control_runagent");

            if (!EvalContextVariableGet(ctx, ref, &retval, NULL))
            {
                Log(LOG_LEVEL_ERR, "Unknown lval '%s' in runagent control body", cp->lval);
                VarRefDestroy(ref);
                continue;
            }

            VarRefDestroy(ref);

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_FORCE_IPV4].lval) == 0)
            {
                RUNATTR.copy.force_ipv4 = BooleanFromString(retval.item);
                Log(LOG_LEVEL_VERBOSE, "SET force_ipv4 = %d", RUNATTR.copy.force_ipv4);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_TRUSTKEY].lval) == 0)
            {
                RUNATTR.copy.trustkey = BooleanFromString(retval.item);
                Log(LOG_LEVEL_VERBOSE, "SET trustkey = %d", RUNATTR.copy.trustkey);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_ENCRYPT].lval) == 0)
            {
                RUNATTR.copy.encrypt = BooleanFromString(retval.item);
                Log(LOG_LEVEL_VERBOSE, "SET encrypt = %d", RUNATTR.copy.encrypt);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_PORT_NUMBER].lval) == 0)
            {
                RUNATTR.copy.portnumber = (unsigned short) IntFromString(retval.item);
                Log(LOG_LEVEL_VERBOSE, "SET default portnumber = %u", RUNATTR.copy.portnumber);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_BACKGROUND].lval) == 0)
            {
                /*
                 * Only process this option if are is no -b or -i options specified on
                 * command line.
                 */
                if (BACKGROUND || INTERACTIVE)
                {
                    Log(LOG_LEVEL_WARNING,
                          "'background_children' setting from 'body runagent control' is overriden by command-line option.");
                }
                else
                {
                    BACKGROUND = BooleanFromString(retval.item);
                }
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_MAX_CHILD].lval) == 0)
            {
                MAXCHILD = (short) IntFromString(retval.item);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_OUTPUT_TO_FILE].lval) == 0)
            {
                OUTPUT_TO_FILE = BooleanFromString(retval.item);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_OUTPUT_DIRECTORY].lval) == 0)
            {
                if (IsAbsPath(retval.item))
                {
                    strncpy(OUTPUT_DIRECTORY, retval.item, CF_BUFSIZE - 1);
                    Log(LOG_LEVEL_VERBOSE, "Setting output direcory to '%s'", OUTPUT_DIRECTORY);
                }
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_TIMEOUT].lval) == 0)
            {
                RUNATTR.copy.timeout = (short) IntFromString(retval.item);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_HOSTS].lval) == 0)
            {
                if (HOSTLIST == NULL)       // Don't override if command line setting
                {
                    HOSTLIST = retval.item;
                }

                continue;
            }
        }
    }

    if (EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_LASTSEEN_EXPIRE_AFTER, &retval))
    {
        LASTSEENEXPIREAFTER = IntFromString(retval.item) * 60;
    }

}
示例#6
0
文件: expand.c 项目: rcorrieri/core
Rval EvaluateFinalRval(EvalContext *ctx, const Policy *policy,
                       const char *ns, const char *scope,
                       Rval rval, bool forcelist, const Promise *pp)
{
    assert(ctx);
    assert(policy);

    Rval returnval;
    if (rval.type == RVAL_TYPE_SCALAR &&
        IsNakedVar(rval.item, '@'))
    {
        /* Treat lists specially here */
        char naked[CF_MAXVARSIZE];
        GetNaked(naked, rval.item);

        if (IsExpandable(naked))
        {
            returnval = ExpandPrivateRval(ctx, NULL, "this", rval.item, rval.type);
        }
        else
        {
            VarRef *ref = VarRefParseFromScope(naked, scope);
            DataType value_type = CF_DATA_TYPE_NONE;
            const void *value = EvalContextVariableGet(ctx, ref, &value_type);

            if (!value || DataTypeToRvalType(value_type) != RVAL_TYPE_LIST)
            {
                returnval = ExpandPrivateRval(ctx, NULL, "this", rval.item, rval.type);
            }
            else
            {
                returnval.item = ExpandList(ctx, ns, scope, value, true);
                returnval.type = RVAL_TYPE_LIST;
            }

            VarRefDestroy(ref);
        }
    }
    else if (forcelist) /* We are replacing scalar @(name) with list */
    {
        returnval = ExpandPrivateRval(ctx, ns, scope, rval.item, rval.type);
    }
    else if (FnCallIsBuiltIn(rval))
    {
        returnval = RvalCopy(rval);
    }
    else
    {
        returnval = ExpandPrivateRval(ctx, NULL, "this", rval.item, rval.type);
    }

    switch (returnval.type)
    {
    case RVAL_TYPE_SCALAR:
    case RVAL_TYPE_CONTAINER:
        break;

    case RVAL_TYPE_LIST:
        for (Rlist *rp = RvalRlistValue(returnval); rp; rp = rp->next)
        {
            switch (rp->val.type)
            {
            case RVAL_TYPE_FNCALL:
            {
                FnCall *fp = RlistFnCallValue(rp);
                rp->val = FnCallEvaluate(ctx, policy, fp, pp).rval;
                FnCallDestroy(fp);
                break;
            }
            case RVAL_TYPE_SCALAR:
                if (EvalContextStackCurrentPromise(ctx) &&
                    IsCf3VarString(RlistScalarValue(rp)))
                {
                    void *prior = rp->val.item;
                    rp->val = ExpandPrivateRval(ctx, NULL, "this",
                                                prior, RVAL_TYPE_SCALAR);
                    free(prior);
                }
                /* else: returnval unchanged. */
                break;
            default:
                assert(!"Bad type for entry in Rlist");
            }
        }
        break;

    case RVAL_TYPE_FNCALL:
        if (FnCallIsBuiltIn(returnval))
        {
            FnCall *fp = RvalFnCallValue(returnval);
            returnval = FnCallEvaluate(ctx, policy, fp, pp).rval;
            FnCallDestroy(fp);
        }
        break;

    default:
        assert(returnval.item == NULL); /* else we're leaking it */
        returnval.item = NULL;
        returnval.type = RVAL_TYPE_NOPROMISEE;
        break;
    }

    return returnval;
}
示例#7
0
文件: expand.c 项目: rcorrieri/core
bool ExpandScalar(const EvalContext *ctx,
                  const char *ns, const char *scope, const char *string,
                  Buffer *out)
{
    assert(string);

    bool returnval = true;

    if (strlen(string) == 0)
    {
        return false;
    }

    // TODO: cleanup, optimize this mess
    Buffer *var = BufferNew();
    Buffer *current_item = BufferNew();
    Buffer *temp = BufferNew();
    for (const char *sp = string; /* No exit */ ; sp++)     /* check for varitems */
    {
        char varstring = false;
        size_t increment = 0;

        if (*sp == '\0')
        {
            break;
        }

        BufferZero(current_item);
        ExtractScalarPrefix(current_item, sp, strlen(sp));

        BufferAppend(out, BufferData(current_item), BufferSize(current_item));
        sp += BufferSize(current_item);

        if (*sp == '\0')
        {
            break;
        }

        BufferZero(var);
        if (*sp == '$')
        {
            switch (*(sp + 1))
            {
            case '(':
                varstring = ')';
                ExtractScalarReference(var, sp, strlen(sp), false);
                if (BufferSize(var) == 0)
                {
                    BufferAppendChar(out, '$');
                    continue;
                }
                break;

            case '{':
                varstring = '}';
                ExtractScalarReference(var, sp, strlen(sp), false);
                if (BufferSize(var) == 0)
                {
                    BufferAppendChar(out, '$');
                    continue;
                }
                break;

            default:
                BufferAppendChar(out, '$');
                continue;
            }
        }

        BufferZero(current_item);
        {
            BufferZero(temp);
            ExtractScalarReference(temp, sp, strlen(sp), true);

            if (IsCf3VarString(BufferData(temp)))
            {
                ExpandScalar(ctx, ns, scope, BufferData(temp), current_item);
            }
            else
            {
                BufferAppend(current_item, BufferData(temp), BufferSize(temp));
            }
        }

        increment = BufferSize(var) - 1;

        char name[CF_MAXVARSIZE] = "";
        if (!IsExpandable(BufferData(current_item)))
        {
            DataType type = CF_DATA_TYPE_NONE;
            const void *value = NULL;
            {
                VarRef *ref = VarRefParseFromNamespaceAndScope(BufferData(current_item), ns, scope, CF_NS, '.');
                value = EvalContextVariableGet(ctx, ref, &type);
                VarRefDestroy(ref);
            }

            if (value)
            {
                switch (type)
                {
                case CF_DATA_TYPE_STRING:
                case CF_DATA_TYPE_INT:
                case CF_DATA_TYPE_REAL:
                    BufferAppend(out, value, strlen(value));
                    break;

                case CF_DATA_TYPE_STRING_LIST:
                case CF_DATA_TYPE_INT_LIST:
                case CF_DATA_TYPE_REAL_LIST:
                case CF_DATA_TYPE_NONE:
                    if (varstring == '}')
                    {
                        snprintf(name, CF_MAXVARSIZE, "${%s}", BufferData(current_item));
                    }
                    else
                    {
                        snprintf(name, CF_MAXVARSIZE, "$(%s)", BufferData(current_item));
                    }

                    BufferAppend(out, name, strlen(name));
                    returnval = false;
                    break;

                default:
                    Log(LOG_LEVEL_DEBUG, "Returning Unknown Scalar ('%s' => '%s')", string, BufferData(out));
                    BufferDestroy(var);
                    BufferDestroy(current_item);
                    BufferDestroy(temp);
                    return false;

                }
            }
            else
            {
                if (varstring == '}')
                {
                    snprintf(name, CF_MAXVARSIZE, "${%s}", BufferData(current_item));
                }
                else
                {
                    snprintf(name, CF_MAXVARSIZE, "$(%s)", BufferData(current_item));
                }

                BufferAppend(out, name, strlen(name));
                returnval = false;
            }
        }

        sp += increment;
        BufferZero(current_item);
    }

    BufferDestroy(var);
    BufferDestroy(current_item);
    BufferDestroy(temp);

    return returnval;
}
示例#8
0
文件: expand.c 项目: rcorrieri/core
static void ExpandAndMapIteratorsFromScalar(EvalContext *ctx,
                                            const Bundle *bundle,
                                            char *string, size_t length,
                                            int level,
                                            Rlist **scalars, Rlist **lists,
                                            Rlist **containers,
                                            Rlist **full_expansion)
{
    assert(string);
    if (!string)
    {
        return;
    }

    Buffer *value = BufferNew();

    for (size_t i = 0; i < length; i++)
    {
        const char *sp = string + i;

        Rlist *tmp_list = NULL;
        BufferZero(value);
        if (ExtractScalarPrefix(value, sp, length - i))
        {
            if (full_expansion)
            {
                RlistConcatInto(&tmp_list, *full_expansion, BufferData(value));
                RlistDestroy(*full_expansion);
                *full_expansion = tmp_list;
                tmp_list = NULL;
            }

            sp += BufferSize(value);
            i += BufferSize(value);

            BufferZero(value);

            if (i >= length)
            {
                break;
            }
        }

        if (*sp == '$')
        {
            BufferZero(value);
            ExtractScalarReference(value, sp, length - i, true);
            if (BufferSize(value) > 0)
            {
                Rlist *inner_expansion = NULL;
                Rlist *exp = NULL;
                int success = 0;

                VarRef *ref = VarRefParse(BufferData(value));

                int increment = BufferSize(value) - 1 + 3;

                // Handle any embedded variables
                char *substring = string + i + 2;
                ExpandAndMapIteratorsFromScalar(ctx, bundle, substring, BufferSize(value), level+1, scalars, lists, containers, &inner_expansion);

                for (exp = inner_expansion; exp != NULL; exp = exp->next)
                {
                    // If a list is non-local, i.e. $(bundle.var), map it to local $(bundle#var)

                    // NB without modifying variables as we map them, it's not
                    // possible to handle remote lists referenced by a variable
                    // scope. For example:
                    //  scope => "test."; var => "somelist"; $($(scope)$(var)) fails
                    //  varname => "test.somelist"; $($(varname)) also fails
                    // TODO Unless the consumer handles it?

                    const char *inner_ref_str = RlistScalarValue(exp);
                    VarRef *inner_ref = VarRefParseFromBundle(inner_ref_str, bundle);

                    // var is the expanded name of the variable in its native context
                    // finalname will be the mapped name in the local context "this."

                    DataType value_type = CF_DATA_TYPE_NONE;
                    const void *value = EvalContextVariableGet(ctx, inner_ref, &value_type);
                    if (value)
                    {
                        char *mangled_inner_ref = xstrdup(inner_ref_str);
                        MangleVarRefString(mangled_inner_ref, strlen(mangled_inner_ref));

                        success++;
                        switch (DataTypeToRvalType(value_type))
                        {
                        case RVAL_TYPE_LIST:
                            if (level > 0)
                            {
                                RlistPrependScalarIdemp(lists, mangled_inner_ref);
                            }
                            else
                            {
                                RlistAppendScalarIdemp(lists, mangled_inner_ref);
                            }

                            if (full_expansion)
                            {
                                for (const Rlist *rp = value; rp != NULL; rp = rp->next)
                                {
                                    // append each slist item to each of full_expansion
                                    RlistConcatInto(&tmp_list, *full_expansion, RlistScalarValue(rp));
                                }
                            }
                            break;

                        case RVAL_TYPE_SCALAR:
                            RlistAppendScalarIdemp(scalars, mangled_inner_ref);

                            if (full_expansion)
                            {
                                // append the scalar value to each of full_expansion
                                RlistConcatInto(&tmp_list, *full_expansion, value);
                            }
                            break;

                        case RVAL_TYPE_CONTAINER:
                            if (level > 0)
                            {
                                RlistPrependScalarIdemp(containers, mangled_inner_ref);
                            }
                            else
                            {
                                RlistAppendScalarIdemp(containers, mangled_inner_ref);
                            }
                            break;

                        case RVAL_TYPE_FNCALL:
                        case RVAL_TYPE_NOPROMISEE:
                            break;
                        }

                        free(mangled_inner_ref);
                    }

                    VarRefDestroy(inner_ref);
                }
                RlistDestroy(inner_expansion);

                if (full_expansion)
                {
                    RlistDestroy(*full_expansion);
                    *full_expansion = tmp_list;
                    tmp_list = NULL;
                }

                // No need to map this.* even though it's technically qualified
                if (success && IsQualifiedVariable(BufferData(value)) && strcmp(ref->scope, "this") != 0)
                {
                    char *dotpos = strchr(substring, '.');
                    if (dotpos)
                    {
                        *dotpos = CF_MAPPEDLIST;    // replace '.' with '#'
                    }

                    if (strchr(BufferData(value), ':'))
                    {
                        char *colonpos = strchr(substring, ':');
                        if (colonpos)
                        {
                            *colonpos = '*';
                        }
                    }
                }

                VarRefDestroy(ref);

                sp += increment;
                i += increment;
            }
        }
    }

    BufferDestroy(value);
}
示例#9
0
文件: expand.c 项目: awsiv/core
bool ExpandScalar(const EvalContext *ctx,
                  const char *ns, const char *scope, const char *string,
                  Buffer *out)
{
    assert(string);
    if (strlen(string) == 0)
    {
        return true;
    }

    bool fully_expanded = true;

    Buffer *current_item = BufferNew();
    for (const char *sp = string; *sp != '\0'; sp++)
    {
        BufferClear(current_item);
        ExtractScalarPrefix(current_item, sp, strlen(sp));

        BufferAppend(out, BufferData(current_item), BufferSize(current_item));
        sp += BufferSize(current_item);
        if (*sp == '\0')
        {
            break;
        }

        BufferClear(current_item);
        char varstring = sp[1];
        ExtractScalarReference(current_item,  sp, strlen(sp), true);
        sp += BufferSize(current_item) + 2;

        if (IsCf3VarString(BufferData(current_item)))
        {
            Buffer *temp = BufferCopy(current_item);
            BufferClear(current_item);
            ExpandScalar(ctx, ns, scope, BufferData(temp), current_item);
            BufferDestroy(temp);
        }

        if (!IsExpandable(BufferData(current_item)))
        {
            DataType type = CF_DATA_TYPE_NONE;
            const void *value = NULL;
            {
                VarRef *ref = VarRefParseFromNamespaceAndScope(BufferData(current_item), ns, scope, CF_NS, '.');
                value = EvalContextVariableGet(ctx, ref, &type);
                VarRefDestroy(ref);
            }

            if (value)
            {
                switch (DataTypeToRvalType(type))
                {
                case RVAL_TYPE_SCALAR:
                    BufferAppendString(out, value);
                    continue;

                case RVAL_TYPE_CONTAINER:
                    if (JsonGetElementType((JsonElement*)value) == JSON_ELEMENT_TYPE_PRIMITIVE)
                    {
                        BufferAppendString(out, JsonPrimitiveGetAsString((JsonElement*)value));
                        continue;
                    }
                    break;

                default:
                    break;
                }
            }
        }

        if (varstring == '{')
        {
            BufferAppendF(out, "${%s}", BufferData(current_item));
        }
        else
        {
            BufferAppendF(out, "$(%s)", BufferData(current_item));
        }
    }

    BufferDestroy(current_item);

    return fully_expanded;
}