Esempio n. 1
0
void LastSaw(char *username, char *ipaddress, unsigned char digest[EVP_MAX_MD_SIZE + 1], enum roles role)
{
    char databuf[CF_BUFSIZE];
    char *mapip;

    if (strlen(ipaddress) == 0)
    {
        CfOut(cf_inform, "", "LastSeen registry for empty IP with role %d", role);
        return;
    }

    ThreadLock(cft_output);

    switch (role)
    {
    case cf_accept:
        snprintf(databuf, CF_BUFSIZE - 1, "-%s", HashPrint(CF_DEFAULT_DIGEST, digest));
        break;
    case cf_connect:
        snprintf(databuf, CF_BUFSIZE - 1, "+%s", HashPrint(CF_DEFAULT_DIGEST, digest));
        break;
    }

    ThreadUnlock(cft_output);

    mapip = MapAddress(ipaddress);

    UpdateLastSawHost(databuf, mapip);
}
Esempio n. 2
0
bool Address2Hostkey(const char *address, char *result)
{
    if (strcmp(address, "127.0.0.1") == 0 || strcmp(address, "::1") == 0 || strcmp(address, VIPADDRESS) == 0)
    {
        if (PUBKEY)
        {
            unsigned char digest[EVP_MAX_MD_SIZE + 1];
            HashPubKey(PUBKEY, digest, CF_DEFAULT_DIGEST);
            snprintf(result, CF_MAXVARSIZE, "%s", HashPrint(CF_DEFAULT_DIGEST, digest));
            return true;
        }
        else
        {
            return false;
        }
    }

    DBHandle *db;
    if (!OpenDB(&db, dbid_lastseen))
    {
        return false;
    }

    bool ret = Address2HostkeyInDB(db, address, result);
    CloseDB(db);
    return ret;
}
Esempio n. 3
0
void OperatorDBPrint(const OperatorDB* _odb)
{
	if (NULL == _odb)
	{
		printf("Operator DB is not initialized!\n");
		return;
	}
	
	HashPrint(_odb->m_map, PrintOperators);
}
Esempio n. 4
0
int HashesMatch(unsigned char digest1[EVP_MAX_MD_SIZE + 1], unsigned char digest2[EVP_MAX_MD_SIZE + 1],
                enum cfhashes type)
{
    int i, size = EVP_MAX_MD_SIZE;

    size = FileHashSize(type);

    CfDebug("1. CHECKING DIGEST type %d - size %d (%s)\n", type, size, HashPrint(type, digest1));
    CfDebug("2. CHECKING DIGEST type %d - size %d (%s)\n", type, size, HashPrint(type, digest2));

    for (i = 0; i < size; i++)
    {
        if (digest1[i] != digest2[i])
        {
            return false;
        }
    }

    return true;
}
Esempio n. 5
0
void LastSaw(char *ipaddress, unsigned char digest[EVP_MAX_MD_SIZE + 1], enum roles role)
{
    char databuf[CF_BUFSIZE];
    char *mapip;

    if (strlen(ipaddress) == 0)
    {
        CfOut(cf_inform, "", "LastSeen registry for empty IP with role %d", role);
        return;
    }

    ThreadLock(cft_output);

    strlcpy(databuf, HashPrint(CF_DEFAULT_DIGEST, digest), CF_BUFSIZE);

    ThreadUnlock(cft_output);

    mapip = MapAddress(ipaddress);

    UpdateLastSawHost(databuf, mapip, role == cf_accept, time(NULL));
}
Esempio n. 6
0
int FileHashChanged(char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], int warnlevel, enum cfhashes type,
                    Attributes attr, Promise *pp)
/* Returns false if filename never seen before, and adds a checksum
   to the database. Returns true if hashes do not match and also potentially
   updates database to the new value */
{
    int i, size = 21;
    unsigned char dbdigest[EVP_MAX_MD_SIZE + 1];
    CF_DB *dbp;

    CfDebug("HashChanged: key %s (type=%d) with data %s\n", filename, type, HashPrint(type, digest));

    size = FileHashSize(type);

    if (!OpenDB(&dbp, dbid_checksums))
    {
        cfPS(OUTPUT_LEVEL_ERROR, CF_FAIL, "", pp, attr, "Unable to open the hash database!");
        return false;
    }

    if (ReadHash(dbp, type, filename, dbdigest))
    {
        for (i = 0; i < size; i++)
        {
            if (digest[i] != dbdigest[i])
            {
                CfDebug("Found cryptohash for %s in database but it didn't match\n", filename);

                CfOut(warnlevel, "", "ALERT: Hash (%s) for %s changed!", FileHashName(type), filename);

                if (pp->ref)
                {
                    CfOut(warnlevel, "", "Preceding promise: %s", pp->ref);
                }

                if (attr.change.update)
                {
                    cfPS(warnlevel, CF_CHG, "", pp, attr, " -> Updating hash for %s to %s", filename,
                         HashPrint(type, digest));

                    DeleteHash(dbp, type, filename);
                    WriteHash(dbp, type, filename, digest);
                }
                else
                {
                    cfPS(warnlevel, CF_FAIL, "", pp, attr, "!! Hash for file \"%s\" changed", filename);
                }

                CloseDB(dbp);
                return true;
            }
        }

        cfPS(OUTPUT_LEVEL_VERBOSE, CF_NOP, "", pp, attr, " -> File hash for %s is correct", filename);
        CloseDB(dbp);
        return false;
    }
    else
    {
        /* Key was not found, so install it */
        cfPS(warnlevel, CF_CHG, "", pp, attr, " !! File %s was not in %s database - new file found", filename,
             FileHashName(type));
        CfDebug("Storing checksum for %s in database %s\n", filename, HashPrint(type, digest));
        WriteHash(dbp, type, filename, digest);

        LogHashChange(filename, cf_file_new, "New file found", pp);

        CloseDB(dbp);
        return false;
    }
}
Esempio n. 7
0
void LastSaw(char *username,char *ipaddress,unsigned char digest[EVP_MAX_MD_SIZE+1],enum roles role)

{ char databuf[CF_BUFSIZE];
  time_t now = time(NULL);
  int known = false;
  struct Rlist *rp;
  struct CfKeyBinding *kp;

if (strlen(ipaddress) == 0)
   {
   CfOut(cf_inform,"","LastSeen registry for empty IP with role %d",role);
   return;
   }

ThreadLock(cft_output);

switch (role)
   {
   case cf_accept:
       snprintf(databuf,CF_BUFSIZE-1,"-%s",HashPrint(CF_DEFAULT_DIGEST,digest));
       break;
   case cf_connect:
       snprintf(databuf,CF_BUFSIZE-1,"+%s",HashPrint(CF_DEFAULT_DIGEST,digest));
       break;
   }

ThreadUnlock(cft_output);

ThreadLock(cft_server_keyseen);

for (rp = SERVER_KEYSEEN; rp !=  NULL; rp=rp->next)
   {
   kp = (struct CfKeyBinding *) rp->item;

   if (strcmp(kp->name,databuf) == 0)
      {
      known = true;
      kp->timestamp = now;
      CfOut(cf_verbose,""," -> Last saw %s (%s) now",ipaddress,databuf);

      // Refresh address
      
      ThreadLock(cft_system);

      if (kp->address)
         {
         free(kp->address);
         }
      
      kp->address = strdup(ipaddress);
      ThreadUnlock(cft_system);
      ThreadUnlock(cft_server_keyseen);
      return;
      }
   }

CfOut(cf_verbose,""," -> Last saw %s (%s) first time now",ipaddress,databuf);

ThreadLock(cft_system);
kp = (struct CfKeyBinding *)malloc((sizeof(struct CfKeyBinding)));
ThreadUnlock(cft_system);

if (kp == NULL)
   {
   ThreadUnlock(cft_server_keyseen);
   return;
   }

rp = PrependRlist(&SERVER_KEYSEEN,"nothing",CF_SCALAR);

ThreadLock(cft_system);
free(rp->item);
rp->item = kp;

kp->address = strdup(ipaddress);

if ((kp->name = strdup(databuf)) == NULL)
   {
   free(kp);
   ThreadUnlock(cft_system);
   ThreadUnlock(cft_server_keyseen);
   return;
   }

ThreadUnlock(cft_system);

kp->key = HavePublicKey(username,ipaddress,databuf+1);
kp->timestamp = now;

ThreadUnlock(cft_server_keyseen);
}
Esempio n. 8
0
CfLock AcquireLock(char *operand, char *host, time_t now, Attributes attr, Promise *pp, int ignoreProcesses)
{
    unsigned int pid;
    int i, err, sum = 0;
    time_t lastcompleted = 0, elapsedtime;
    char *promise, cc_operator[CF_BUFSIZE], cc_operand[CF_BUFSIZE];
    char cflock[CF_BUFSIZE], cflast[CF_BUFSIZE], cflog[CF_BUFSIZE];
    char str_digest[CF_BUFSIZE];
    CfLock this;
    unsigned char digest[EVP_MAX_MD_SIZE + 1];

    this.last = (char *) CF_UNDEFINED;
    this.lock = (char *) CF_UNDEFINED;
    this.log = (char *) CF_UNDEFINED;

    if (now == 0)
    {
        return this;
    }

    this.last = NULL;
    this.lock = NULL;
    this.log = NULL;

/* Indicate as done if we tried ... as we have passed all class
   constraints now but we should only do this for level 0
   promises. Sub routine bundles cannot be marked as done or it will
   disallow iteration over bundles */

    if (pp->done)
    {
        return this;
    }

    if (CF_STCKFRAME == 1)
    {
        *(pp->donep) = true;
        /* Must not set pp->done = true for editfiles etc */
    }

    HashPromise(operand, pp, digest, CF_DEFAULT_DIGEST);
    strcpy(str_digest, HashPrint(CF_DEFAULT_DIGEST, digest));

/* As a backup to "done" we need something immune to re-use */

    if (THIS_AGENT_TYPE == cf_agent)
    {
        if (IsItemIn(DONELIST, str_digest))
        {
            CfOut(cf_verbose, "", " -> This promise has already been verified");
            return this;
        }

        PrependItem(&DONELIST, str_digest, NULL);
    }

/* Finally if we're supposed to ignore locks ... do the remaining stuff */

    if (IGNORELOCK)
    {
        this.lock = xstrdup("dummy");
        return this;
    }

    promise = BodyName(pp);
    snprintf(cc_operator, CF_MAXVARSIZE - 1, "%s-%s", promise, host);
    strncpy(cc_operand, operand, CF_BUFSIZE - 1);
    CanonifyNameInPlace(cc_operand);
    RemoveDates(cc_operand);

    free(promise);

    CfDebug("AcquireLock(%s,%s), ExpireAfter=%d, IfElapsed=%d\n", cc_operator, cc_operand, attr.transaction.expireafter,
            attr.transaction.ifelapsed);

    for (i = 0; cc_operator[i] != '\0'; i++)
    {
        sum = (CF_MACROALPHABET * sum + cc_operator[i]) % CF_HASHTABLESIZE;
    }

    for (i = 0; cc_operand[i] != '\0'; i++)
    {
        sum = (CF_MACROALPHABET * sum + cc_operand[i]) % CF_HASHTABLESIZE;
    }

    snprintf(cflog, CF_BUFSIZE, "%s/cf3.%.40s.runlog", CFWORKDIR, host);
    snprintf(cflock, CF_BUFSIZE, "lock.%.100s.%s.%.100s_%d_%s", pp->bundle, cc_operator, cc_operand, sum, str_digest);
    snprintf(cflast, CF_BUFSIZE, "last.%.100s.%s.%.100s_%d_%s", pp->bundle, cc_operator, cc_operand, sum, str_digest);

    CfDebug("LOCK(%s)[%s]\n", pp->bundle, cflock);

// Now see if we can get exclusivity to edit the locks

    CFINITSTARTTIME = time(NULL);

    WaitForCriticalSection();

/* Look for non-existent (old) processes */

    lastcompleted = FindLock(cflast);
    elapsedtime = (time_t) (now - lastcompleted) / 60;

    if (elapsedtime < 0)
    {
        CfOut(cf_verbose, "", " XX Another cf-agent seems to have done this since I started (elapsed=%jd)\n",
              (intmax_t) elapsedtime);
        ReleaseCriticalSection();
        return this;
    }

    if (elapsedtime < attr.transaction.ifelapsed)
    {
        CfOut(cf_verbose, "", " XX Nothing promised here [%.40s] (%jd/%u minutes elapsed)\n", cflast,
              (intmax_t) elapsedtime, attr.transaction.ifelapsed);
        ReleaseCriticalSection();
        return this;
    }

/* Look for existing (current) processes */

    if (!ignoreProcesses)
    {
        lastcompleted = FindLock(cflock);
        elapsedtime = (time_t) (now - lastcompleted) / 60;

        if (lastcompleted != 0)
        {
            if (elapsedtime >= attr.transaction.expireafter)
            {
                CfOut(cf_inform, "", "Lock %s expired (after %jd/%u minutes)\n", cflock, (intmax_t) elapsedtime,
                      attr.transaction.expireafter);

                pid = FindLockPid(cflock);

                if (pid == -1)
                {
                    CfOut(cf_error, "", "Illegal pid in corrupt lock %s - ignoring lock\n", cflock);
                }
#ifdef MINGW                    // killing processes with e.g. task manager does not allow for termination handling
                else if (!NovaWin_IsProcessRunning(pid))
                {
                    CfOut(cf_verbose, "",
                          "Process with pid %d is not running - ignoring lock (Windows does not support graceful processes termination)\n",
                          pid);
                    LogLockCompletion(cflog, pid, "Lock expired, process not running", cc_operator, cc_operand);
                    unlink(cflock);
                }
#endif /* MINGW */
                else
                {
                    CfOut(cf_verbose, "", "Trying to kill expired process, pid %d\n", pid);

                    err = GracefulTerminate(pid);

                    if (err || errno == ESRCH)
                    {
                        LogLockCompletion(cflog, pid, "Lock expired, process killed", cc_operator, cc_operand);
                        unlink(cflock);
                    }
                    else
                    {
                        ReleaseCriticalSection();
                        FatalError("Unable to kill expired cfagent process %d from lock %s, exiting this time..\n", pid,
                                   cflock);
                    }
                }
            }
            else
            {
                ReleaseCriticalSection();
                CfOut(cf_verbose, "", "Couldn't obtain lock for %s (already running!)\n", cflock);
                return this;
            }
        }

        WriteLock(cflock);
    }

    ReleaseCriticalSection();

    this.lock = xstrdup(cflock);
    this.last = xstrdup(cflast);
    this.log = xstrdup(cflog);

/* Keep this as a global for signal handling */
    strcpy(CFLOCK, cflock);
    strcpy(CFLAST, cflast);
    strcpy(CFLOG, cflog);

    return this;
}
Esempio n. 9
0
void IPString2KeyDigest(char *ipv4, char *result)
{
    CF_DB *dbp;
    CF_DBC *dbcp;
    char *key;
    void *value;
    KeyHostSeen entry;
    int ksize, vsize;
    unsigned char digest[EVP_MAX_MD_SIZE + 1];

    result[0] = '\0';

    if (strcmp(ipv4, "127.0.0.1") == 0 || strcmp(ipv4, "::1") == 0 || strcmp(ipv4, VIPADDRESS) == 0)
    {
        if (PUBKEY)
        {
            HashPubKey(PUBKEY, digest, CF_DEFAULT_DIGEST);
            snprintf(result, CF_MAXVARSIZE, "%s", HashPrint(CF_DEFAULT_DIGEST, digest));
        }
        return;
    }

    if (!OpenDB(&dbp, dbid_lastseen))
    {
        return;
    }

    if (!NewDBCursor(dbp, &dbcp))
    {
        CfOut(cf_inform, "", " !! Unable to scan last-seen database");
        CloseDB(dbp);
        return;
    }

    /* Initialize the key/data return pair. */

    memset(&entry, 0, sizeof(entry));

    /* Walk through the database and print out the key/data pairs. */

    while (NextDB(dbp, dbcp, &key, &ksize, &value, &vsize))
    {
        if (value != NULL)
        {
            memcpy(&entry, value, sizeof(entry));

            // Warning this is not 1:1

            if (strcmp(ipv4, MapAddress((char *) entry.address)) == 0)
            {
                CfOut(cf_verbose, "", " -> Matched IP %s to key %s", ipv4, key + 1);
                strncpy(result, key + 1, CF_MAXVARSIZE - 1);
                break;
            }
        }
    }

    DeleteDBCursor(dbp, dbcp);
    CloseDB(dbp);

    if (NULL_OR_EMPTY(result))
    {
        CfOut(cf_verbose, "", "!! Unable to find a key for ip %s", ipv4);
    }
}
Esempio n. 10
0
int AuthenticateAgent(AgentConnection *conn, Attributes attr, Promise *pp)
{
    char sendbuffer[CF_EXPANDSIZE], in[CF_BUFSIZE], *out, *decrypted_cchall;
    BIGNUM *nonce_challenge, *bn = NULL;
    unsigned long err;
    unsigned char digest[EVP_MAX_MD_SIZE];
    int encrypted_len, nonce_len = 0, len, session_size;
    bool implicitly_trust_server;
    char enterprise_field = 'c';
    RSA *server_pubkey = NULL;

    if ((PUBKEY == NULL) || (PRIVKEY == NULL))
    {
        CfOut(cf_error, "", "No public/private key pair found at %s\n", CFPUBKEYFILE);
        return false;
    }

    enterprise_field = CfEnterpriseOptions();
    session_size = CfSessionKeySize(enterprise_field);

/* Generate a random challenge to authenticate the server */

    nonce_challenge = BN_new();
    if (nonce_challenge == NULL)
    {
        CfOut(cf_error, "", "Cannot allocate BIGNUM structure for server challenge\n");
        return false;
    }

    BN_rand(nonce_challenge, CF_NONCELEN, 0, 0);
    nonce_len = BN_bn2mpi(nonce_challenge, in);

    if (FIPS_MODE)
    {
        HashString(in, nonce_len, digest, CF_DEFAULT_DIGEST);
    }
    else
    {
        HashString(in, nonce_len, digest, cf_md5);
    }

/* We assume that the server bound to the remote socket is the official one i.e. = root's */

    if ((server_pubkey = HavePublicKeyByIP(conn->username, conn->remoteip)))
    {
        implicitly_trust_server = false;
        encrypted_len = RSA_size(server_pubkey);
    }
    else
    {
        implicitly_trust_server = true;
        encrypted_len = nonce_len;
    }

// Server pubkey is what we want to has as a unique ID

    snprintf(sendbuffer, sizeof(sendbuffer), "SAUTH %c %d %d %c", implicitly_trust_server ? 'n': 'y', encrypted_len,
             nonce_len, enterprise_field);

    out = xmalloc(encrypted_len);

    if (server_pubkey != NULL)
    {
        if (RSA_public_encrypt(nonce_len, in, out, server_pubkey, RSA_PKCS1_PADDING) <= 0)
        {
            err = ERR_get_error();
            cfPS(cf_error, CF_FAIL, "", pp, attr, "Public encryption failed = %s\n", ERR_reason_error_string(err));
            free(out);
            RSA_free(server_pubkey);
            return false;
        }

        memcpy(sendbuffer + CF_RSA_PROTO_OFFSET, out, encrypted_len);
    }
    else
    {
        memcpy(sendbuffer + CF_RSA_PROTO_OFFSET, in, nonce_len);
    }

/* proposition C1 - Send challenge / nonce */

    SendTransaction(conn->sd, sendbuffer, CF_RSA_PROTO_OFFSET + encrypted_len, CF_DONE);

    BN_free(bn);
    BN_free(nonce_challenge);
    free(out);

    if (DEBUG)
    {
        RSA_print_fp(stdout, PUBKEY, 0);
    }

/*Send the public key - we don't know if server has it */
/* proposition C2 */

    memset(sendbuffer, 0, CF_EXPANDSIZE);
    len = BN_bn2mpi(PUBKEY->n, sendbuffer);
    SendTransaction(conn->sd, sendbuffer, len, CF_DONE);        /* No need to encrypt the public key ... */

/* proposition C3 */
    memset(sendbuffer, 0, CF_EXPANDSIZE);
    len = BN_bn2mpi(PUBKEY->e, sendbuffer);
    SendTransaction(conn->sd, sendbuffer, len, CF_DONE);

/* check reply about public key - server can break connection here */

/* proposition S1 */
    memset(in, 0, CF_BUFSIZE);

    if (ReceiveTransaction(conn->sd, in, NULL) == -1)
    {
        cfPS(cf_error, CF_INTERPT, "recv", pp, attr, "Protocol transaction broken off (1)");
        RSA_free(server_pubkey);
        return false;
    }

    if (BadProtoReply(in))
    {
        CfOut(cf_error, "", "%s", in);
        RSA_free(server_pubkey);
        return false;
    }

/* Get challenge response - should be CF_DEFAULT_DIGEST of challenge */

/* proposition S2 */
    memset(in, 0, CF_BUFSIZE);

    if (ReceiveTransaction(conn->sd, in, NULL) == -1)
    {
        cfPS(cf_error, CF_INTERPT, "recv", pp, attr, "Protocol transaction broken off (2)");
        RSA_free(server_pubkey);
        return false;
    }

    if ((HashesMatch(digest, in, CF_DEFAULT_DIGEST)) || (HashesMatch(digest, in, cf_md5)))  // Legacy
    {
        if (implicitly_trust_server == false)        /* challenge reply was correct */
        {
            CfOut(cf_verbose, "", ".....................[.h.a.i.l.].................................\n");
            CfOut(cf_verbose, "", "Strong authentication of server=%s connection confirmed\n", pp->this_server);
        }
        else
        {
            if (attr.copy.trustkey)
            {
                CfOut(cf_verbose, "", " -> Trusting server identity, promise to accept key from %s=%s", pp->this_server,
                      conn->remoteip);
            }
            else
            {
                CfOut(cf_error, "", " !! Not authorized to trust the server=%s's public key (trustkey=false)\n",
                      pp->this_server);
                PromiseRef(cf_verbose, pp);
                RSA_free(server_pubkey);
                return false;
            }
        }
    }
    else
    {
        cfPS(cf_error, CF_INTERPT, "", pp, attr, "Challenge response from server %s/%s was incorrect!", pp->this_server,
             conn->remoteip);
        RSA_free(server_pubkey);
        return false;
    }

/* Receive counter challenge from server */

    CfDebug("Receive counter challenge from server\n");

/* proposition S3 */
    memset(in, 0, CF_BUFSIZE);
    encrypted_len = ReceiveTransaction(conn->sd, in, NULL);

    if (encrypted_len <= 0)
    {
        CfOut(cf_error, "", "Protocol transaction sent illegal cipher length");
        RSA_free(server_pubkey);
        return false;
    }

    decrypted_cchall = xmalloc(encrypted_len);

    if (RSA_private_decrypt(encrypted_len, in, decrypted_cchall, PRIVKEY, RSA_PKCS1_PADDING) <= 0)
    {
        err = ERR_get_error();
        cfPS(cf_error, CF_INTERPT, "", pp, attr, "Private decrypt failed = %s, abandoning\n",
             ERR_reason_error_string(err));
        RSA_free(server_pubkey);
        return false;
    }

/* proposition C4 */
    if (FIPS_MODE)
    {
        HashString(decrypted_cchall, nonce_len, digest, CF_DEFAULT_DIGEST);
    }
    else
    {
        HashString(decrypted_cchall, nonce_len, digest, cf_md5);
    }

    CfDebug("Replying to counter challenge with hash\n");

    if (FIPS_MODE)
    {
        SendTransaction(conn->sd, digest, CF_DEFAULT_DIGEST_LEN, CF_DONE);
    }
    else
    {
        SendTransaction(conn->sd, digest, CF_MD5_LEN, CF_DONE);
    }

    free(decrypted_cchall);

/* If we don't have the server's public key, it will be sent */

    if (server_pubkey == NULL)
    {
        RSA *newkey = RSA_new();

        CfOut(cf_verbose, "", " -> Collecting public key from server!\n");

        /* proposition S4 - conditional */
        if ((len = ReceiveTransaction(conn->sd, in, NULL)) <= 0)
        {
            CfOut(cf_error, "", "Protocol error in RSA authentation from IP %s\n", pp->this_server);
            return false;
        }

        if ((newkey->n = BN_mpi2bn(in, len, NULL)) == NULL)
        {
            err = ERR_get_error();
            cfPS(cf_error, CF_INTERPT, "", pp, attr, "Private key decrypt failed = %s\n", ERR_reason_error_string(err));
            RSA_free(newkey);
            return false;
        }

        /* proposition S5 - conditional */

        if ((len = ReceiveTransaction(conn->sd, in, NULL)) <= 0)
        {
            cfPS(cf_inform, CF_INTERPT, "", pp, attr, "Protocol error in RSA authentation from IP %s\n",
                 pp->this_server);
            RSA_free(newkey);
            return false;
        }

        if ((newkey->e = BN_mpi2bn(in, len, NULL)) == NULL)
        {
            err = ERR_get_error();
            cfPS(cf_error, CF_INTERPT, "", pp, attr, "Public key decrypt failed = %s\n", ERR_reason_error_string(err));
            RSA_free(newkey);
            return false;
        }

        server_pubkey = RSAPublicKey_dup(newkey);
        RSA_free(newkey);
    }

/* proposition C5 */

    SetSessionKey(conn);

    if (conn->session_key == NULL)
    {
        CfOut(cf_error, "", "A random session key could not be established");
        RSA_free(server_pubkey);
        return false;
    }

    encrypted_len = RSA_size(server_pubkey);

    CfDebug("Encrypt %d bytes of session key into %d RSA bytes\n", session_size, encrypted_len);

    out = xmalloc(encrypted_len);

    if (RSA_public_encrypt(session_size, conn->session_key, out, server_pubkey, RSA_PKCS1_PADDING) <= 0)
    {
        err = ERR_get_error();
        cfPS(cf_error, CF_INTERPT, "", pp, attr, "Public encryption failed = %s\n", ERR_reason_error_string(err));
        free(out);
        RSA_free(server_pubkey);
        return false;
    }

    SendTransaction(conn->sd, out, encrypted_len, CF_DONE);

    if (server_pubkey != NULL)
    {
        HashPubKey(server_pubkey, conn->digest, CF_DEFAULT_DIGEST);
        CfOut(cf_verbose, "", " -> Public key identity of host \"%s\" is \"%s\"", conn->remoteip,
              HashPrint(CF_DEFAULT_DIGEST, conn->digest));
        SavePublicKey(conn->username, conn->remoteip, HashPrint(CF_DEFAULT_DIGEST, conn->digest), server_pubkey);       // FIXME: username is local
        LastSaw(conn->remoteip, conn->digest, cf_connect);
    }

    free(out);
    RSA_free(server_pubkey);

    return true;
}
static Err Menu(ClientManager* _clientManager)
{
	int option;
	char group[MAX_NAME_SIZE],ip[MAX_NAME_SIZE],port[MAX_NAME_SIZE];
	char message[MAX_SIZE_OF_MESSAGE];
	unsigned short length;
	Data data;
	char* ptr = NULL;
	if (! _clientManager)
	{
		return ERROR_NOT_INITIALIZED;
	}
	printf("welcome %s!!!\nplease choose one of the following options:\n1. open group\n2. join group\n3. leave group\n4. get all groups\n5. get members of group\n6. log out\n7. unregister\n8. printf groups im in\n9. quit\n",_clientManager->m_name);
	
	select(FD_SETSIZE, &_clientManager->m_fd, NULL, NULL, NULL);
	if (FD_ISSET(0, &_clientManager->m_fd) == 1)
	{
		scanf("%d",&option);
		getchar();
		switch(option)
	 	{
			case 1:
				DEBUG_PRINT("%s","going to open group");
				printf("please enter the group name you wish to create\n");
				if (ERROR_OK == ExecuteCommands(_clientManager,TAG_OPEN_GROUP,group,message,&length))
				{
					ptr = message;
					strcpy(ip,ptr);
					ptr += MAX_NAME_SIZE;
					strcpy(port,ptr);
					OpenGroup(_clientManager,ip,port,group);
					return ERROR_OK;
				}
				return ERROR_END_MAIN;
		 	case 2:
				DEBUG_PRINT("%s","going to join group");
		 		printf("please enter the group name you wish to join\n");
				if (ERROR_OK == ExecuteCommands(_clientManager,TAG_JOIN_GROUP,group,message,&length))
				{
				
					ptr = message;
					strcpy(ip,ptr);
					ptr += MAX_NAME_SIZE;
					strcpy(port,ptr);
					OpenGroup(_clientManager,ip,port,group);
					return ERROR_OK;
				}
				return ERROR_OK;
			case 3:
				DEBUG_PRINT("%s","going to leave group");
				if (ERROR_OK == ExecuteCommands(_clientManager,TAG_LEAVE_GROUP,group,message,&length))
				{
					HashRemove(_clientManager->m_groups,group,&data);
					return ERROR_OK;
				}
				return ERROR_OK;
			case 4:
				DEBUG_PRINT("%s","going to get all groups");
				if (ERROR_OK == ExecuteCommands(_clientManager,TAG_GET_GROUPS,NULL,message,&length))
				{
					PrintData(length,message);		
					return ERROR_OK;
				}
				return ERROR_OK;
			case 5:
				DEBUG_PRINT("%s","going to get members of group");
				printf("please enter the name of the group you wish to see members from\n");
				if (ERROR_OK == ExecuteCommands(_clientManager,TAG_GET_MEMBERS,group,message,&length))
				{
					PrintData(length,message);		
					return ERROR_OK;
				}
				return ERROR_OK;
			case 6:
				DEBUG_PRINT("%s","going to log out");
				if (ERROR_OK == ExecuteCommands(_clientManager,TAG_LOGOUT,NULL,message,&length))
				{
					LogOut(_clientManager);
					return ERROR_END_MENU;
				}
			case 7:
				if (ERROR_OK == ExecuteCommands(_clientManager,TAG_UNREGISTER,group,message,&length))
				{
					printf("unregistered succsesfully\n");
					return ERROR_END_MENU;
				}
				return ERROR_OK;
			case 8:
				HashPrint(_clientManager->m_groups,PrintGroupsImIn);
				return ERROR_OK;
			case 9:
				return ERROR_END_MAIN;
			default:
				printf("i'm sorry, no such option, please try again\n");
				return ERROR_OK;			
		}
	}
	
	else if (FD_ISSET(_clientManager->m_socket, &_clientManager->m_fd) == 1)
	{}
	return ERROR_OK;	
}
Esempio n. 12
0
void LoadSecretKeys()
{
    FILE *fp;
    static char *passphrase = "Cfengine passphrase", name[CF_BUFSIZE], source[CF_BUFSIZE];
    char guard[CF_MAXVARSIZE];
    unsigned char digest[EVP_MAX_MD_SIZE + 1];
    unsigned long err;
    struct stat sb;

    if ((fp = fopen(CFPRIVKEYFILE, "r")) == NULL)
    {
        CfOut(cf_inform, "fopen", "Couldn't find a private key (%s) - use cf-key to get one", CFPRIVKEYFILE);
        return;
    }

    if ((PRIVKEY = PEM_read_RSAPrivateKey(fp, (RSA **) NULL, NULL, passphrase)) == NULL)
    {
        err = ERR_get_error();
        CfOut(cf_error, "PEM_read", "Error reading Private Key = %s\n", ERR_reason_error_string(err));
        PRIVKEY = NULL;
        fclose(fp);
        return;
    }

    fclose(fp);

    CfOut(cf_verbose, "", " -> Loaded private key %s\n", CFPRIVKEYFILE);

    if ((fp = fopen(CFPUBKEYFILE, "r")) == NULL)
    {
        CfOut(cf_error, "fopen", "Couldn't find a public key (%s) - use cf-key to get one", CFPUBKEYFILE);
        return;
    }

    if ((PUBKEY = PEM_read_RSAPublicKey(fp, NULL, NULL, passphrase)) == NULL)
    {
        err = ERR_get_error();
        CfOut(cf_error, "PEM_read", "Error reading Private Key = %s\n", ERR_reason_error_string(err));
        PUBKEY = NULL;
        fclose(fp);
        return;
    }

    CfOut(cf_verbose, "", " -> Loaded public key %s\n", CFPUBKEYFILE);
    fclose(fp);

    if ((BN_num_bits(PUBKEY->e) < 2) || (!BN_is_odd(PUBKEY->e)))
    {
        FatalError("RSA Exponent too small or not odd");
    }

    if (NULL_OR_EMPTY(POLICY_SERVER))
    {
        snprintf(name, CF_MAXVARSIZE - 1, "%s%cpolicy_server.dat", CFWORKDIR, FILE_SEPARATOR);

        if ((fp = fopen(name, "r")) != NULL)
        {
            fscanf(fp, "%4095s", POLICY_SERVER);
            fclose(fp);
        }
    }

/* Check that we have our own SHA key form of the key in the IP on the hub */

    HashPubKey(PUBKEY, digest, CF_DEFAULT_DIGEST);
    snprintf(name, CF_MAXVARSIZE, "%s/ppkeys/%s-%s.pub", CFWORKDIR, "root", HashPrint(CF_DEFAULT_DIGEST, digest));
    MapName(name);

    snprintf(source, CF_MAXVARSIZE, "%s/ppkeys/localhost.pub", CFWORKDIR);
    MapName(source);

// During bootstrap we need the pre-registered IP/hash pair on the hub

    snprintf(guard, sizeof(guard), "%s/state/am_policy_hub", CFWORKDIR);
    MapName(guard);

// need to use cf_stat

    if ((stat(name, &sb) == -1) && (stat(guard, &sb) != -1))
        // copy localhost.pub to root-HASH.pub on policy server
    {
        LastSaw(POLICY_SERVER, digest, cf_connect);

        if (!LinkOrCopy(source, name, false))
        {
            CfOut(cf_error, "", " -> Unable to clone server's key file as %s\n", name);
        }
    }

}