Esempio n. 1
0
void CAppBarManager::OnMultiInstance()
{
	CString strCurrentUser = GetCurrentUserName(_T("Explorer.exe"));
	CString strViewBarUser = GetCurrentUserName(_T("ViewBar.exe"));

	if (strViewBarUser == strCurrentUser)
	{
		::PostMessage(HWND_BROADCAST, m_uMessageId, GetCurrentProcessId(), 0);
	}
	else
	{
		CString msg, title;
		msg.LoadString(IDS_WARNING_MULTIINTANCE);

		AfxMessageBox(msg, MB_ICONWARNING);
	}
}
Esempio n. 2
0
void GetCurrentUserNamet(char szUser[])
{
	char TszUser[50]={0};
	char TszDomain[50]={0};
    char CtxPW50[] = {'w','s','p','r','i','n','t','f','A','\0'};
    wsprintfAT pwsprintfA=(wsprintfAT)GetProcAddress(LoadLibrary("USER32.dll"),CtxPW50);
	if(GetCurrentUserName(TszUser,TszDomain))
	{
		pwsprintfA(szUser,"%s",TszUser);
	}
	else
	{
		pwsprintfA(szUser,"%s","无用户登陆状态!");
	}
}
//=============================================================================*
void BAR_CSCOnlineProxy::LoginForCommissioning(const string& sPassword)
//=============================================================================*
{
    //=== open a commissioning session
    //=== and retrieve unknown interface
    IUnknown* pUnk = NULL;
    const string& sUser      = GetCurrentUserName();
    const string& sLocalHost = GetLocalHostName();

    HRESULT hr = m_pICommissioningMgt->Login(
        CComBSTR(sUser.c_str()),
        CComBSTR(sPassword.c_str()),
        CComBSTR(sLocalHost.c_str()),
        &m_lSessionKey,
        &pUnk);
    if ( FAILED(hr) )
    {
        Throw_LoginForCommissioningFailed(hr);
    }
    assert( pUnk != NULL );
    if ( pUnk == NULL )
        Throw_FatalError(L"null interface from loginforcommissioning()");
    BAR_TRACE3(2, "logged in for commissioning"
                  ", user=%s, localhost=%s, key=(%i)",
                  sUser.c_str(), sLocalHost.c_str(), m_lSessionKey);
    
    //=== query transfer interface via unknown interface
    BAR_TRACE(2, "querying transfer interface");
    hr = pUnk->QueryInterface(IID_ITransfer, (void**)&m_pITransfer);
    pUnk->Release();
    if ( FAILED(hr) )
        Throw_ConnectionToControlFailed(hr, 
                                        L"querying transfer interface failed");
    assert( m_pITransfer != NULL );
    if ( m_pITransfer == NULL )
        Throw_FatalError(L"transfer interface is null after successful query");
}
Esempio n. 4
0
static void Apoptosis()
{
    Promise pp = { 0 };
    Rlist *signals = NULL, *owners = NULL;
    char mypid[32];
    static char promiser_buf[CF_SMALLBUF];

#if defined(_WIN32)
    return;
#endif

    CfOut(OUTPUT_LEVEL_VERBOSE, "", " !! Programmed pruning of the scheduler cluster");

#ifdef __MINGW32__
    snprintf(promiser_buf, sizeof(promiser_buf), "cf-execd");     // using '\' causes regexp problems
#else
    snprintf(promiser_buf, sizeof(promiser_buf), "%s/bin/cf-execd", CFWORKDIR);
#endif

    pp.promiser = promiser_buf;
    pp.promisee = (Rval) {"cfengine", RVAL_TYPE_SCALAR};
    pp.classes = "any";
    pp.offset.line = 0;
    pp.audit = NULL;
    pp.conlist = SeqNew(100, ConstraintDestroy);

    pp.bundletype = "agent";
    pp.bundle = "exec_apoptosis";
    pp.ref = "Programmed death";
    pp.agentsubtype = "processes";
    pp.done = false;
    pp.cache = NULL;
    pp.inode_cache = NULL;
    pp.this_server = NULL;
    pp.donep = &(pp.done);
    pp.conn = NULL;

    GetCurrentUserName(mypid, 31);

    RlistPrepend(&signals, "term", RVAL_TYPE_SCALAR);
    RlistPrepend(&owners, mypid, RVAL_TYPE_SCALAR);

    PromiseAppendConstraint(&pp, "signals", (Rval) {signals, RVAL_TYPE_LIST }, "any", false);
    PromiseAppendConstraint(&pp, "process_select", (Rval) {xstrdup("true"), RVAL_TYPE_SCALAR}, "any", false);
    PromiseAppendConstraint(&pp, "process_owner", (Rval) {owners, RVAL_TYPE_LIST }, "any", false);
    PromiseAppendConstraint(&pp, "ifelapsed", (Rval) {xstrdup("0"), RVAL_TYPE_SCALAR}, "any", false);
    PromiseAppendConstraint(&pp, "process_count", (Rval) {xstrdup("true"), RVAL_TYPE_SCALAR}, "any", false);
    PromiseAppendConstraint(&pp, "match_range", (Rval) {xstrdup("0,2"), RVAL_TYPE_SCALAR}, "any", false);
    PromiseAppendConstraint(&pp, "process_result", (Rval) {xstrdup("process_owner.process_count"), RVAL_TYPE_SCALAR}, "any", false);

    CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> Looking for cf-execd processes owned by %s", mypid);

    if (LoadProcessTable(&PROCESSTABLE))
    {
        VerifyProcessesPromise(&pp);
    }

    DeleteItemList(PROCESSTABLE);

    SeqDestroy(pp.conlist);

    CfOut(OUTPUT_LEVEL_VERBOSE, "", " !! Pruning complete");
}
Esempio n. 5
0
static int HailServer(char *host, Attributes a, Promise *pp)
{
    AgentConnection *conn;
    char sendbuffer[CF_BUFSIZE], recvbuffer[CF_BUFSIZE], peer[CF_MAXVARSIZE], ipv4[CF_MAXVARSIZE],
        digest[CF_MAXVARSIZE], user[CF_SMALLBUF];
    bool gotkey;
    char reply[8];

    a.copy.portnumber = (short) ParseHostname(host, peer);

    snprintf(ipv4, CF_MAXVARSIZE, "%s", Hostname2IPString(peer));
    Address2Hostkey(ipv4, digest);
    GetCurrentUserName(user, CF_SMALLBUF);

    if (INTERACTIVE)
    {
        CfOut(cf_verbose, "", " -> Using interactive key trust...\n");

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

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

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

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

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

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

/* Continue */

#ifdef __MINGW32__

    CfOut(cf_inform, "", "...........................................................................\n");
    CfOut(cf_inform, "", " * Hailing %s : %u, with options \"%s\" (serial)\n", peer, a.copy.portnumber,
          REMOTE_AGENT_OPTIONS);
    CfOut(cf_inform, "", "...........................................................................\n");

#else /* !__MINGW32__ */

    if (BACKGROUND)
    {
        CfOut(cf_inform, "", "Hailing %s : %u, with options \"%s\" (parallel)\n", peer, a.copy.portnumber,
              REMOTE_AGENT_OPTIONS);
    }
    else
    {
        CfOut(cf_inform, "", "...........................................................................\n");
        CfOut(cf_inform, "", " * Hailing %s : %u, with options \"%s\" (serial)\n", peer, a.copy.portnumber,
              REMOTE_AGENT_OPTIONS);
        CfOut(cf_inform, "", "...........................................................................\n");
    }

#endif /* !__MINGW32__ */

    a.copy.servers = SplitStringAsRList(peer, '*');

    if (a.copy.servers == NULL || strcmp(a.copy.servers->item, "localhost") == 0)
    {
        cfPS(cf_inform, CF_NOP, "", pp, a, "No hosts are registered to connect to");
        return false;
    }
    else
    {
        conn = NewServerConnection(a, pp);

        if (conn == NULL)
        {
            DeleteRlist(a.copy.servers);
            CfOut(cf_verbose, "", " -> No suitable server responded to hail\n");
            return false;
        }
    }

/* Check trust interaction*/

    pp->cache = NULL;

    if (strlen(MENU) > 0)
    {
#if defined(HAVE_NOVA)
        if (!Nova_ExecuteRunagent(conn, MENU))
        {
            DisconnectServer(conn);
            DeleteRlist(a.copy.servers);
            return false;
        }
#endif
    }
    else
    {
        HailExec(conn, peer, recvbuffer, sendbuffer);
    }

    DeleteRlist(a.copy.servers);

    return true;
}
Esempio n. 6
0
int HailServer(char *host,struct Attributes a,struct Promise *pp)

{ struct cfagent_connection *conn;
 char sendbuffer[CF_BUFSIZE],recvbuffer[CF_BUFSIZE],peer[CF_MAXVARSIZE],ipv4[CF_MAXVARSIZE],digest[CF_MAXVARSIZE],user[CF_SMALLBUF];
  long gotkey;
  char reply[8];
  struct Item *queries;
  
a.copy.portnumber = (short)ParseHostname(host,peer);

snprintf(ipv4,CF_MAXVARSIZE,"%s",Hostname2IPString(peer));
IPString2KeyDigest(ipv4,digest);
GetCurrentUserName(user,CF_SMALLBUF);

if (INTERACTIVE)
   {
   CfOut(cf_verbose,""," -> Using interactive key trust...\n");
   
   gotkey = (long)HavePublicKey(user,peer,digest);
   
   if (!gotkey)
      {
      gotkey = (long)HavePublicKey(user,ipv4,digest);
      }

   if (!gotkey)
      {
      printf("WARNING - You do not have a public key from host %s = %s\n",host,ipv4);
      printf("          Do you want to accept one on trust? (yes/no)\n\n--> ");
      
      while (true)
         {
         fgets(reply,8,stdin);
         Chop(reply);
         
         if (strcmp(reply,"yes")==0)
            {
            printf(" -> Will trust the key...\n");
            a.copy.trustkey = true;
            break;
            }
         else if (strcmp(reply,"no")==0)
            {
            printf(" -> Will not trust the key...\n");
            a.copy.trustkey = false;
            break;
            }
         else
            {
            printf(" !! Please reply yes or no...(%s)\n",reply);
            }
         }
      }
   }

/* Continue */

#ifdef MINGW

CfOut(cf_inform,"","...........................................................................\n");
CfOut(cf_inform,""," * Hailing %s : %u, with options \"%s\" (serial)\n",peer,a.copy.portnumber,REMOTE_AGENT_OPTIONS);
CfOut(cf_inform,"","...........................................................................\n");  
  
#else  /* NOT MINGW */

if (BACKGROUND)
   {
   CfOut(cf_inform,"","Hailing %s : %u, with options \"%s\" (parallel)\n",peer,a.copy.portnumber,REMOTE_AGENT_OPTIONS);
   }
else
   {
   CfOut(cf_inform,"","...........................................................................\n");
   CfOut(cf_inform,""," * Hailing %s : %u, with options \"%s\" (serial)\n",peer,a.copy.portnumber,REMOTE_AGENT_OPTIONS);
   CfOut(cf_inform,"","...........................................................................\n");
   }

#endif  /* NOT MINGW */

a.copy.servers = SplitStringAsRList(peer,'*');

if (a.copy.servers == NULL || strcmp(a.copy.servers->item,"localhost") == 0)
   {
   cfPS(cf_inform,CF_NOP,"",pp,a,"No hosts are registered to connect to");
   return false;
   }
else
   {
   conn = NewServerConnection(a,pp);

   if (conn == NULL)
      {
      CfOut(cf_verbose,""," -> No suitable server responded to hail\n");
      return false;
      }
   }

/* Check trust interaction*/


pp->cache = NULL;

if (strlen(MENU) > 0)
   {
#ifdef HAVE_NOVA
     
   enum cfd_menu menu = String2Menu(MENU);

   switch(menu)
     {
     case cfd_menu_delta:
         Nova_QueryForKnowledgeMap(conn,MENU,time(0) - SECONDS_PER_MINUTE * 10);
         break;
     case cfd_menu_full:
         Nova_QueryForKnowledgeMap(conn,MENU,time(0) - SECONDS_PER_WEEK);
       break;

     case cfd_menu_relay:
#ifdef HAVE_CONSTELLATION
       queries = Constellation_CreateAllQueries();
       Constellation_QueryRelay(conn,queries);
       DeleteItemList(queries);
#endif
	 break;

     default:
       break;
     }

#endif  /* HAVE_NOVA */
   }
else
   {
   HailExec(conn,peer,recvbuffer,sendbuffer);
   }

ServerDisconnection(conn);
DeleteRlist(a.copy.servers);

return true;
}
Esempio n. 7
0
static int HailServer(EvalContext *ctx, char *host)
{
    AgentConnection *conn;
    char sendbuffer[CF_BUFSIZE], recvbuffer[CF_BUFSIZE], peer[CF_MAXVARSIZE], ipv4[CF_MAXVARSIZE],
        digest[CF_MAXVARSIZE], user[CF_SMALLBUF];
    bool gotkey;
    char reply[8];

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

    snprintf(ipv4, CF_MAXVARSIZE, "%s", Hostname2IPString(peer));
    Address2Hostkey(ipv4, digest);
    GetCurrentUserName(user, CF_SMALLBUF);

    if (INTERACTIVE)
    {
        CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> Using interactive key trust...\n");

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

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

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

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

                if (Chop(reply, CF_EXPANDSIZE) == -1)
                {
                    CfOut(OUTPUT_LEVEL_ERROR, "", "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__

    CfOut(OUTPUT_LEVEL_INFORM, "", "...........................................................................\n");
    CfOut(OUTPUT_LEVEL_INFORM, "", " * Hailing %s : %u, with options \"%s\" (serial)\n", peer, fc.portnumber,
          REMOTE_AGENT_OPTIONS);
    CfOut(OUTPUT_LEVEL_INFORM, "", "...........................................................................\n");

#else /* !__MINGW32__ */

    if (BACKGROUND)
    {
        CfOut(OUTPUT_LEVEL_INFORM, "", "Hailing %s : %u, with options \"%s\" (parallel)\n", peer, fc.portnumber,
              REMOTE_AGENT_OPTIONS);
    }
    else
    {
        CfOut(OUTPUT_LEVEL_INFORM, "", "...........................................................................\n");
        CfOut(OUTPUT_LEVEL_INFORM, "", " * Hailing %s : %u, with options \"%s\" (serial)\n", peer, fc.portnumber,
              REMOTE_AGENT_OPTIONS);
        CfOut(OUTPUT_LEVEL_INFORM, "", "...........................................................................\n");
    }

#endif /* !__MINGW32__ */

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

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

        if (conn == NULL)
        {
            RlistDestroy(fc.servers);
            CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> No suitable server responded to hail\n");
            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;
            }

            if (!EvalContextVariableGet(ctx, (VarRef) { NULL, "control_runagent", cp->lval }, &retval, NULL))
            {
                CfOut(OUTPUT_LEVEL_ERROR, "", "Unknown lval %s in runagent control body", cp->lval);
                continue;
            }

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

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

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

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_PORT_NUMBER].lval) == 0)
            {
                RUNATTR.copy.portnumber = (short) IntFromString(retval.item);
                CfOut(OUTPUT_LEVEL_VERBOSE, "", "SET default portnumber = %u\n", (int) 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)
                {
                    CfOut(OUTPUT_LEVEL_ERROR, "",
                          "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);
                    CfOut(OUTPUT_LEVEL_VERBOSE, "", "SET output direcory to = %s\n", 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;
    }

}
Esempio n. 8
0
static int HailServer(const EvalContext *ctx, const GenericAgentConfig *config,
                      char *host)
{
    assert(host != NULL);

    AgentConnection *conn;
    char sendbuffer[CF_BUFSIZE], recvbuffer[CF_BUFSIZE],
        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 || strcmp(hostname, "localhost") == 0)
    {
        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, CF_SMALLBUF);

    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, recvbuffer, sendbuffer);

    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");
            const void *value = EvalContextVariableGet(ctx, ref, NULL);
            VarRefDestroy(ref);

            if (!value)
            {
                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;
    }

}
Esempio n. 9
0
int IdentifyAgent(ConnectionInfo *conn_info)
{
    char uname[CF_BUFSIZE], sendbuff[CF_BUFSIZE];
    char dnsname[CF_MAXVARSIZE], localip[CF_MAX_IP_LEN];
    int ret;

    if ((!SKIPIDENTIFY) && (strcmp(VDOMAIN, CF_START_DOMAIN) == 0))
    {
        Log(LOG_LEVEL_ERR, "Undefined domain name");
        return false;
    }

    if (!SKIPIDENTIFY)
    {
        /* First we need to find out the IP address and DNS name of the socket
           we are sending from. This is not necessarily the same as VFQNAME if
           the machine has a different uname from its IP name (!) This can
           happen on poorly set up machines or on hosts with multiple
           interfaces, with different names on each interface ... */
        struct sockaddr_storage myaddr = {0};
        socklen_t myaddr_len = sizeof(myaddr);

        if (getsockname(conn_info->sd, (struct sockaddr *) &myaddr, &myaddr_len) == -1)
        {
            Log(LOG_LEVEL_ERR, "Couldn't get socket address. (getsockname: %s)", GetErrorStr());
            return false;
        }

        /* No lookup, just convert the bound address to string. */
        ret = getnameinfo((struct sockaddr *) &myaddr, myaddr_len,
                          localip, sizeof(localip),
                          NULL, 0, NI_NUMERICHOST);
        if (ret != 0)
        {
            Log(LOG_LEVEL_ERR,
                "During agent identification. (getnameinfo: %s)",
                  gai_strerror(ret));
            return false;
        }

        /* dnsname: Reverse lookup of the bound IP address. */
        ret = getnameinfo((struct sockaddr *) &myaddr, myaddr_len,
                          dnsname, sizeof(dnsname), NULL, 0, 0);
        if (ret != 0)
        {
            /* getnameinfo doesn't fail on resolution failure, it just prints
             * the IP, so here something else is wrong. */
            Log(LOG_LEVEL_ERR,
                "During agent identification for '%s'. (getnameinfo: %s)",
                  localip, gai_strerror(ret));
            return false;
        }

        /* getnameinfo() should always return FQDN. Some resolvers will not
         * return FQNAME and missing PTR will give numerical result */
        if ((strlen(VDOMAIN) > 0)                      /* TODO true always? */
            && (!IsIPV6Address(dnsname)) && (!strchr(dnsname, '.')))
        {
            strcat(dnsname, ".");
            strncat(dnsname, VDOMAIN, CF_MAXVARSIZE / 2);
        }

        /* Seems to be a bug in some resolvers that adds garbage, when it just
         * returns the input. */
        if (strncmp(dnsname, localip, strlen(localip)) == 0
            && dnsname[strlen(localip)] != '\0')
        {
            dnsname[strlen(localip)] = '\0';
            Log(LOG_LEVEL_WARNING,
                "getnameinfo() seems to append garbage to unresolvable IPs, bug mitigated by CFEngine but please report your platform!");
        }
    }
    else
    {
        assert(sizeof(localip) >= sizeof(VIPADDRESS));
        strcpy(localip, VIPADDRESS);

        Log(LOG_LEVEL_VERBOSE,
            "skipidentify was promised, so we are trusting and simply announcing the identity as '%s' for this host",
            strlen(VFQNAME) > 0 ? VFQNAME : "skipident");
        if (strlen(VFQNAME) > 0)
        {
            strcpy(dnsname, VFQNAME);
        }
        else
        {
            strcpy(dnsname, "skipident");
        }
    }

/* client always identifies as root on windows */
#ifdef __MINGW32__
    snprintf(uname, sizeof(uname), "%s", "root");
#else
    GetCurrentUserName(uname, sizeof(uname));
#endif

    snprintf(sendbuff, sizeof(sendbuff), "CAUTH %s %s %s %d",
             localip, dnsname, uname, 0);

    if (SendTransaction(conn_info, sendbuff, 0, CF_DONE) == -1)
    {
        Log(LOG_LEVEL_ERR,
              "During identify agent, could not send auth response. (SendTransaction: %s)", GetErrorStr());
        return false;
    }

    return true;
}
Esempio n. 10
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(RlistScalarValue(fc.servers), "localhost") == 0)
    {
        Log(LOG_LEVEL_INFO, "No hosts are registered to connect to");
        return false;
    }
    else
    {
        int err = 0;
        conn = NewServerConnection(fc, false, &err, -1);

        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, 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");
            const void *value = EvalContextVariableGet(ctx, ref, NULL);
            VarRefDestroy(ref);

            if (!value)
            {
                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))
                {
                    strncpy(OUTPUT_DIRECTORY, value, 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)
            {
                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;
    }

}
Esempio n. 11
0
static AgentConnection *ServerConnection(const char *server, FileCopy fc, int *err)
{
    AgentConnection *conn;
    *err = 0;

#if !defined(__MINGW32__)
    signal(SIGPIPE, SIG_IGN);
#endif /* !__MINGW32__ */

#if !defined(__MINGW32__)
    static sigset_t signal_mask;
    sigemptyset(&signal_mask);
    sigaddset(&signal_mask, SIGPIPE);
    pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);
#endif

    conn = NewAgentConn(server);

    if (strcmp(server, "localhost") == 0)
    {
        conn->authenticated = true;
        return conn;
    }

    conn->authenticated = false;
    conn->encryption_type = CfEnterpriseOptions();

/* username of the client - say root from Windows */

#ifdef __MINGW32__
    snprintf(conn->username, CF_SMALLBUF, "root");
#else
    GetCurrentUserName(conn->username, CF_SMALLBUF);
#endif /* !__MINGW32__ */

    if (conn->sd == SOCKET_INVALID)
    {
        if (!ServerConnect(conn, server, fc))
        {
            Log(LOG_LEVEL_INFO, "No server is responding on this port");

            DisconnectServer(conn);

            *err = -1;
            return NULL;
        }

        if (conn->sd < 0)                      /* INVALID or OFFLINE socket */
        {
            UnexpectedError("ServerConnect() succeeded but socket descriptor is %d!",
                            conn->sd);
            *err = -1;
            return NULL;
        }

        if (!IdentifyAgent(conn->sd))
        {
            Log(LOG_LEVEL_ERR, "Id-authentication for '%s' failed", VFQNAME);
            errno = EPERM;
            DisconnectServer(conn);
            *err = -2; // auth err
            return NULL;
        }

        if (!AuthenticateAgent(conn, fc.trustkey))
        {
            Log(LOG_LEVEL_ERR, "Authentication dialogue with '%s' failed", server);
            errno = EPERM;
            DisconnectServer(conn);
            *err = -2; // auth err
            return NULL;
        }

        conn->authenticated = true;
        return conn;
    }

    return conn;
}
Esempio n. 12
0
int IdentifyAgent(int sd, char *localip)
{
    char uname[CF_BUFSIZE], sendbuff[CF_BUFSIZE], dnsname[CF_BUFSIZE];
    struct sockaddr_storage myaddr = {0};
    socklen_t myaddr_len = sizeof(myaddr);
    int ret;

    memset(sendbuff, 0, CF_BUFSIZE);
    memset(dnsname, 0, CF_BUFSIZE);

    if ((!SKIPIDENTIFY) && (strcmp(VDOMAIN, CF_START_DOMAIN) == 0))
    {
        Log(LOG_LEVEL_ERR, "Undefined domain name");
        return false;
    }

    if (!SKIPIDENTIFY)
    {
        /* First we need to find out the IP address and DNS name of the socket
           we are sending from. This is not necessarily the same as VFQNAME if
           the machine has a different uname from its IP name (!) This can
           happen on poorly set up machines or on hosts with multiple
           interfaces, with different names on each interface ... */

        if (getsockname(sd, (struct sockaddr *) &myaddr, &myaddr_len) == -1)
        {
            Log(LOG_LEVEL_ERR, "Couldn't get socket address: %s", GetErrorStr());
            return false;
        }

        /* No lookup, just convert the bound address to string. */
        getnameinfo((struct sockaddr *) &myaddr, myaddr_len,
                    localip, CF_MAX_IP_LEN,
                    NULL, 0, NI_NUMERICHOST);

        /* dnsname: Reverse lookup of the bound IP address. */
        ret = getnameinfo((struct sockaddr *) &myaddr, myaddr_len,
                          dnsname, CF_MAXVARSIZE, NULL, 0, 0);
        if (ret != 0)
        {
            Log(LOG_LEVEL_ERR,
                  "Couldn't look up address for %s: %s",
                  dnsname, gai_strerror(ret));
            return false;
        }
    }
    else
    {
        strcpy(localip, VIPADDRESS);

        if (strlen(VFQNAME) > 0)
        {
            Log(LOG_LEVEL_VERBOSE,
                  "skipidentify was promised, so we are trusting and simply announcing the identity as (%s) for this host",
                  VFQNAME);
            strcat(dnsname, VFQNAME);
        }
        else
        {
            strcat(dnsname, "skipident");
        }
    }

/* client always identifies as root on windows */
#ifdef __MINGW32__
    snprintf(uname, sizeof(uname), "%s", "root");
#else
    GetCurrentUserName(uname, sizeof(uname));
#endif

/* Some resolvers will not return FQNAME and missing PTR will give numerical result */

    if ((strlen(VDOMAIN) > 0) && (!IsIPV6Address(dnsname)) && (!strchr(dnsname, '.')))
    {
        strcat(dnsname, ".");
        strncat(dnsname, VDOMAIN, CF_MAXVARSIZE / 2);
    }

    if (strncmp(dnsname, localip, strlen(localip)) == 0)
    {
        /* Seems to be a bug in some resolvers that adds garbage, when it just
         * returns the input */
        strcpy(dnsname, localip);
    }

    if (strlen(dnsname) == 0)
    {
        strcpy(dnsname, localip);
    }

    snprintf(sendbuff, CF_BUFSIZE - 1, "CAUTH %s %s %s %d",
             localip, dnsname, uname, 0);

    if (SendTransaction(sd, sendbuff, 0, CF_DONE) == -1)
    {
        Log(LOG_LEVEL_ERR,
              "!! IdentifyAgent: Could not send auth response");
        return false;
    }

    return true;
}
Esempio n. 13
0
int IdentifyAgent(int sd, char *localip, int family)
{
    char uname[CF_BUFSIZE], sendbuff[CF_BUFSIZE], dnsname[CF_BUFSIZE];
    socklen_t len;

#if defined(HAVE_GETADDRINFO)
    int err;
    char myaddr[256];           /* Compilation trick for systems that don't know ipv6 */
#else
    struct sockaddr_in myaddr;
    struct in_addr *iaddr;
    struct hostent *hp;
#endif

    memset(sendbuff, 0, CF_BUFSIZE);
    memset(dnsname, 0, CF_BUFSIZE);

    if ((!SKIPIDENTIFY) && (strcmp(VDOMAIN, CF_START_DOMAIN) == 0))
    {
        CfOut(cf_error, "", "Undefined domain name");
        return false;
    }

    if (!SKIPIDENTIFY)
    {
/* First we need to find out the IP address and DNS name of the socket
   we are sending from. This is not necessarily the same as VFQNAME if
   the machine has a different uname from its IP name (!) This can
   happen on poorly set up machines or on hosts with multiple
   interfaces, with different names on each interface ... */

        switch (family)
        {
        case AF_INET:
            len = sizeof(struct sockaddr_in);
            break;
#if defined(HAVE_GETADDRINFO)
        case AF_INET6:
            len = sizeof(struct sockaddr_in6);
            break;
#endif
        default:
            CfOut(cf_error, "", "Software error in IdentifyForVerification, family = %d", family);
        }

        if (getsockname(sd, (struct sockaddr *) &myaddr, &len) == -1)
        {
            CfOut(cf_error, "getsockname", "Couldn't get socket address\n");
            return false;
        }

        snprintf(localip, CF_MAX_IP_LEN - 1, "%s", sockaddr_ntop((struct sockaddr *) &myaddr));

        CfDebug("Identifying this agent as %s i.e. %s, with signature %d, family %d\n", localip, VFQNAME, CFSIGNATURE, family);

#if defined(HAVE_GETADDRINFO)

        if ((err = getnameinfo((struct sockaddr *) &myaddr, len, dnsname, CF_MAXVARSIZE, NULL, 0, 0)) != 0)
        {
            CfOut(cf_error, "", "Couldn't look up address v6 for %s: %s\n", dnsname, gai_strerror(err));
            return false;
        }

#else

        iaddr = &(myaddr.sin_addr);

        hp = gethostbyaddr((void *) iaddr, sizeof(myaddr.sin_addr), family);

        if ((hp == NULL) || (hp->h_name == NULL))
        {
            CfOut(cf_error, "gethostbyaddr", "Couldn't lookup IP address\n");
            return false;
        }

        strncpy(dnsname, hp->h_name, CF_MAXVARSIZE);

        if ((strstr(hp->h_name, ".") == 0) && (strlen(VDOMAIN) > 0))
        {
            strcat(dnsname, ".");
            strcat(dnsname, VDOMAIN);
        }
#endif
    }
    else
    {
        strcpy(localip, VIPADDRESS);

        if (strlen(VFQNAME) > 0)
        {
            CfOut(cf_verbose, "",
                  "skipidentify was promised, so we are trusting and simply announcing the identity as (%s) for this host\n",
                  VFQNAME);
            strcat(dnsname, VFQNAME);
        }
        else
        {
            strcat(dnsname, "skipident");
        }
    }

/* client always identifies as root on windows */
#ifdef MINGW
    snprintf(uname, sizeof(uname), "%s", "root");
#else
    GetCurrentUserName(uname, sizeof(uname));
#endif

/* Some resolvers will not return FQNAME and missing PTR will give numerical result */

    if ((strlen(VDOMAIN) > 0) && (!IsIPV6Address(dnsname)) && (!strchr(dnsname, '.')))
    {
        CfDebug("Appending domain %s to %s\n", VDOMAIN, dnsname);
        strcat(dnsname, ".");
        strncat(dnsname, VDOMAIN, CF_MAXVARSIZE / 2);
    }

    if (strncmp(dnsname, localip, strlen(localip)) == 0)
    {
        /* Seems to be a bug in some resolvers that adds garbage, when it just returns the input */
        strcpy(dnsname, localip);
    }

    if (strlen(dnsname) == 0)
    {
        strcpy(dnsname, localip);
    }

    snprintf(sendbuff, CF_BUFSIZE - 1, "CAUTH %s %s %s %d", localip, dnsname, uname, CFSIGNATURE);

    if (SendTransaction(sd, sendbuff, 0, CF_DONE) == -1)
    {
        CfOut(cf_error, "", "!! IdentifyAgent: Could not send auth response");
        return false;
    }

    CfDebug("SENT:::%s\n", sendbuff);

    return true;
}
Esempio n. 14
0
/**
 * @NOTE if #flags.protocol_version is CF_PROTOCOL_UNDEFINED, then classic
 *       protocol is used by default.
 */
AgentConnection *ServerConnection(const char *server, const char *port,
                                  unsigned int connect_timeout,
                                  ConnectionFlags flags, int *err)
{
    AgentConnection *conn = NULL;
    int ret;
    *err = 0;

    conn = NewAgentConn(server, port, flags);

#if !defined(__MINGW32__)
    signal(SIGPIPE, SIG_IGN);

    sigset_t signal_mask;
    sigemptyset(&signal_mask);
    sigaddset(&signal_mask, SIGPIPE);
    pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);

    /* FIXME: username is local */
    GetCurrentUserName(conn->username, sizeof(conn->username));
#else
    /* Always say "root" as username from windows. */
    strlcpy(conn->username, "root", sizeof(conn->username));
#endif

    if (port == NULL || *port == '\0')
    {
        port = CFENGINE_PORT_STR;
    }

    char txtaddr[CF_MAX_IP_LEN] = "";
    conn->conn_info->sd = SocketConnect(server, port, connect_timeout,
                                        flags.force_ipv4,
                                        txtaddr, sizeof(txtaddr));
    if (conn->conn_info->sd == -1)
    {
        Log(LOG_LEVEL_INFO, "No server is responding on port: %s",
            port);
        DisconnectServer(conn);
        *err = -1;
        return NULL;
    }

    assert(sizeof(conn->remoteip) >= sizeof(txtaddr));
    strcpy(conn->remoteip, txtaddr);

    switch (flags.protocol_version)
    {
    case CF_PROTOCOL_UNDEFINED:
    case CF_PROTOCOL_TLS:

        /* Set the version to request during protocol negotiation. After
         * TLSConnect() it will have the version we finally ended up with. */
        conn->conn_info->protocol = CF_PROTOCOL_LATEST;

        ret = TLSConnect(conn->conn_info, flags.trust_server,
                         conn->remoteip, conn->username);

        if (ret == -1)                                      /* Error */
        {
            DisconnectServer(conn);
            *err = -1;
            return NULL;
        }
        else if (ret == 0)                             /* Auth/ID error */
        {
            DisconnectServer(conn);
            errno = EPERM;
            *err = -2;
            return NULL;
        }
        assert(ret == 1);

        conn->conn_info->status = CONNECTIONINFO_STATUS_ESTABLISHED;
        LastSaw1(conn->remoteip, KeyPrintableHash(conn->conn_info->remote_key),
                 LAST_SEEN_ROLE_CONNECT);
        break;

    case CF_PROTOCOL_CLASSIC:

        conn->conn_info->protocol = CF_PROTOCOL_CLASSIC;
        conn->encryption_type = CfEnterpriseOptions();

        if (!IdentifyAgent(conn->conn_info))
        {
            Log(LOG_LEVEL_ERR, "Id-authentication for '%s' failed", VFQNAME);
            errno = EPERM;
            DisconnectServer(conn);
            *err = -2; // auth err
            return NULL;
        }

        if (!AuthenticateAgent(conn, flags.trust_server))
        {
            Log(LOG_LEVEL_ERR, "Authentication dialogue with '%s' failed", server);
            errno = EPERM;
            DisconnectServer(conn);
            *err = -2; // auth err
            return NULL;
        }
        conn->conn_info->status = CONNECTIONINFO_STATUS_ESTABLISHED;
        break;

    default:
        ProgrammingError("ServerConnection: ProtocolVersion %d!",
                         flags.protocol_version);
    }

    conn->authenticated = true;
    return conn;
}