int main(int argc, char *argv[]) { EvalContext *ctx = EvalContextNew(); GenericAgentConfig *config = CheckOpts(argc, argv); GenericAgentConfigApply(ctx, config); ReportContext *report_context = OpenReports(ctx, config->agent_type); GenericAgentDiscoverContext(ctx, config, report_context); if (SHOWHOSTS) { ShowLastSeenHosts(); return 0; } if (print_digest_arg) { return PrintDigest(print_digest_arg); } if (REMOVEKEYS) { return RemoveKeys(remove_keys_host); } if(LICENSE_INSTALL) { bool success = LicenseInstall(LICENSE_SOURCE); return success ? 0 : 1; } if (trust_key_arg) { return TrustKey(trust_key_arg); } char *public_key_file, *private_key_file; if (KEY_PATH) { xasprintf(&public_key_file, "%s.pub", KEY_PATH); xasprintf(&private_key_file, "%s.priv", KEY_PATH); } else { public_key_file = xstrdup(PublicKeyFile()); private_key_file = xstrdup(PrivateKeyFile()); } KeepKeyPromises(public_key_file, private_key_file); free(public_key_file); free(private_key_file); ReportContextDestroy(report_context); GenericAgentConfigDestroy(config); EvalContextDestroy(ctx); return 0; }
AgentDiagnosticsResult AgentDiagnosticsCheckPrivateKey(const char *workdir) { const char *path = PrivateKeyFile(workdir); assert(path); struct stat sb; if (stat(path, &sb) != 0) { return AgentDiagnosticsResultNew(false, StringFormat("No private key found at '%s'", path)); } if (sb.st_mode != (S_IFREG | S_IWUSR | S_IRUSR)) { return AgentDiagnosticsResultNew(false, StringFormat("Private key found at '%s', but had incorrect permissions '%o'", path, sb.st_mode)); } return AgentDiagnosticsResultNew(true, StringFormat("OK at '%s'", path)); }
/** * @return true the error is not so severe that we must stop */ bool LoadSecretKeys(const char *policy_server) { static char *passphrase = "Cfengine passphrase"; { FILE *fp = fopen(PrivateKeyFile(GetWorkDir()), "r"); if (!fp) { Log(LOG_LEVEL_INFO, "Couldn't find a private key at '%s', use cf-key to get one. (fopen: %s)", PrivateKeyFile(GetWorkDir()), GetErrorStr()); return true; } if ((PRIVKEY = PEM_read_RSAPrivateKey(fp, (RSA **) NULL, NULL, passphrase)) == NULL) { unsigned long err = ERR_get_error(); Log(LOG_LEVEL_ERR, "Error reading private key. (PEM_read_RSAPrivateKey: %s)", ERR_reason_error_string(err)); PRIVKEY = NULL; fclose(fp); return true; } fclose(fp); Log(LOG_LEVEL_VERBOSE, "Loaded private key at '%s'", PrivateKeyFile(GetWorkDir())); } { FILE *fp = fopen(PublicKeyFile(GetWorkDir()), "r"); if (!fp) { Log(LOG_LEVEL_ERR, "Couldn't find a public key at '%s', use cf-key to get one (fopen: %s)", PublicKeyFile(GetWorkDir()), GetErrorStr()); return true; } if ((PUBKEY = PEM_read_RSAPublicKey(fp, NULL, NULL, passphrase)) == NULL) { unsigned long err = ERR_get_error(); Log(LOG_LEVEL_ERR, "Error reading public key at '%s'. (PEM_read_RSAPublicKey: %s)", PublicKeyFile(GetWorkDir()), ERR_reason_error_string(err)); PUBKEY = NULL; fclose(fp); return true; } Log(LOG_LEVEL_VERBOSE, "Loaded public key '%s'", PublicKeyFile(GetWorkDir())); fclose(fp); } if ((BN_num_bits(PUBKEY->e) < 2) || (!BN_is_odd(PUBKEY->e))) { Log(LOG_LEVEL_ERR, "The public key RSA exponent is too small or not odd"); return false; } if (GetAmPolicyHub(CFWORKDIR)) { unsigned char digest[EVP_MAX_MD_SIZE + 1]; char dst_public_key_filename[CF_BUFSIZE] = ""; { char buffer[EVP_MAX_MD_SIZE * 4]; HashPubKey(PUBKEY, digest, CF_DEFAULT_DIGEST); snprintf(dst_public_key_filename, CF_MAXVARSIZE, "%s/ppkeys/%s-%s.pub", CFWORKDIR, "root", HashPrintSafe(CF_DEFAULT_DIGEST, digest, buffer)); MapName(dst_public_key_filename); } struct stat sb; if ((stat(dst_public_key_filename, &sb) == -1)) { char src_public_key_filename[CF_BUFSIZE] = ""; snprintf(src_public_key_filename, CF_MAXVARSIZE, "%s/ppkeys/localhost.pub", CFWORKDIR); MapName(src_public_key_filename); // copy localhost.pub to root-HASH.pub on policy server if (!LinkOrCopy(src_public_key_filename, dst_public_key_filename, false)) { Log(LOG_LEVEL_ERR, "Unable to copy policy server's own public key from '%s' to '%s'", src_public_key_filename, dst_public_key_filename); } if (policy_server) { LastSaw(policy_server, digest, LAST_SEEN_ROLE_CONNECT); } } } return true; }
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(PrivateKeyFile(), "r")) == NULL) { CfOut(OUTPUT_LEVEL_INFORM, "fopen", "Couldn't find a private key (%s) - use cf-key to get one", PrivateKeyFile()); return; } if ((PRIVKEY = PEM_read_RSAPrivateKey(fp, (RSA **) NULL, NULL, passphrase)) == NULL) { err = ERR_get_error(); CfOut(OUTPUT_LEVEL_ERROR, "PEM_read", "Error reading Private Key = %s\n", ERR_reason_error_string(err)); PRIVKEY = NULL; fclose(fp); return; } fclose(fp); CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> Loaded private key %s\n", PrivateKeyFile()); if ((fp = fopen(PublicKeyFile(), "r")) == NULL) { CfOut(OUTPUT_LEVEL_ERROR, "fopen", "Couldn't find a public key (%s) - use cf-key to get one", PublicKeyFile()); return; } if ((PUBKEY = PEM_read_RSAPublicKey(fp, NULL, NULL, passphrase)) == NULL) { err = ERR_get_error(); CfOut(OUTPUT_LEVEL_ERROR, "PEM_read", "Error reading Private Key = %s\n", ERR_reason_error_string(err)); PUBKEY = NULL; fclose(fp); return; } CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> Loaded public key %s\n", PublicKeyFile()); 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) { if (fscanf(fp, "%4095s", POLICY_SERVER) != 1) { CfDebug("Couldn't read string from policy_server.dat"); } fclose(fp); } } /* Check that we have our own SHA key form of the key in the IP on the hub */ char buffer[EVP_MAX_MD_SIZE * 4]; HashPubKey(PUBKEY, digest, CF_DEFAULT_DIGEST); snprintf(name, CF_MAXVARSIZE, "%s/ppkeys/%s-%s.pub", CFWORKDIR, "root", HashPrintSafe(CF_DEFAULT_DIGEST, digest, buffer)); 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, LAST_SEEN_ROLE_CONNECT); if (!LinkOrCopy(source, name, false)) { CfOut(OUTPUT_LEVEL_ERROR, "", " -> Unable to clone server's key file as %s\n", name); } } }
int main(int argc, char *argv[]) { SetupSignalsForCfKey(HandleSignalsForAgent); GenericAgentConfig *config = CheckOpts(argc, argv); EvalContext *ctx = EvalContextNew(); GenericAgentConfigApply(ctx, config); GenericAgentDiscoverContext(ctx, config); if (SHOWHOSTS) { SetupSignalsForCfKey(handleShowKeysSignal); ShowLastSeenHosts(); return 0; } if (print_digest_arg) { return PrintDigest(print_digest_arg); } GenericAgentPostLoadInit(ctx); if (REMOVEKEYS) { int status; if (FORCEREMOVAL) { if (!strncmp(remove_keys_host, "SHA=", 3) || !strncmp(remove_keys_host, "MD5=", 3)) { status = ForceKeyRemoval(remove_keys_host); } else { status = ForceIpAddressRemoval(remove_keys_host); } } else { status = RemoveKeys(remove_keys_host, true); if (status == 0 || status == 1) { Log (LOG_LEVEL_VERBOSE, "Forced removal of entry '%s' was successful", remove_keys_host); return 0; } } return status; } if(LICENSE_INSTALL) { bool success = LicenseInstall(LICENSE_SOURCE); return success ? 0 : 1; } if (trust_key_arg != NULL) { char *filename, *ipaddr, *username; /* We will modify the argument to --trust-key. */ char *arg = xstrdup(trust_key_arg); ParseKeyArg(arg, &filename, &ipaddr, &username); /* Server IP address required to trust key on the client side. */ if (ipaddr == NULL) { Log(LOG_LEVEL_NOTICE, "Establishing trust might be incomplete. " "For completeness, use --trust-key IPADDR:filename"); } bool ret = TrustKey(filename, ipaddr, username); free(arg); return ret ? EXIT_SUCCESS : EXIT_FAILURE; } char *public_key_file, *private_key_file; if (KEY_PATH) { xasprintf(&public_key_file, "%s.pub", KEY_PATH); xasprintf(&private_key_file, "%s.priv", KEY_PATH); } else { public_key_file = PublicKeyFile(GetWorkDir()); private_key_file = PrivateKeyFile(GetWorkDir()); } bool ret = KeepKeyPromises(public_key_file, private_key_file, KEY_SIZE); free(public_key_file); free(private_key_file); GenericAgentFinalize(ctx, config); return ret ? EXIT_SUCCESS : EXIT_FAILURE; }
/** * @return true the error is not so severe that we must stop */ bool LoadSecretKeys(void) { { char *privkeyfile = PrivateKeyFile(GetWorkDir()); FILE *fp = fopen(privkeyfile, "r"); if (!fp) { Log(CryptoGetMissingKeyLogLevel(), "Couldn't find a private key at '%s', use cgn-key to get one. (fopen: %s)", privkeyfile, GetErrorStr()); free(privkeyfile); return false; } PRIVKEY = PEM_read_RSAPrivateKey(fp, NULL, NULL, (void*) priv_passphrase); if (PRIVKEY == NULL) { Log(LOG_LEVEL_VERBOSE, "Error reading private key. (PEM_read_RSAPrivateKey: %s)", CryptoLastErrorString()); PRIVKEY = NULL; fclose(fp); return false; } fclose(fp); Log(LOG_LEVEL_VERBOSE, "Loaded private key at '%s'", privkeyfile); free(privkeyfile); } { char *pubkeyfile = PublicKeyFile(GetWorkDir()); FILE *fp = fopen(pubkeyfile, "r"); if (!fp) { Log(CryptoGetMissingKeyLogLevel(), "Couldn't find a public key at '%s', use cgn-key to get one (fopen: %s)", pubkeyfile, GetErrorStr()); free(pubkeyfile); return false; } PUBKEY = PEM_read_RSAPublicKey(fp, NULL, NULL, (void*) priv_passphrase); if (NULL == PUBKEY) { Log(LOG_LEVEL_ERR, "Error reading public key at '%s'. (PEM_read_RSAPublicKey: %s)", pubkeyfile, CryptoLastErrorString()); fclose(fp); free(pubkeyfile); return false; } Log(LOG_LEVEL_VERBOSE, "Loaded public key '%s'", pubkeyfile); free(pubkeyfile); fclose(fp); } if (NULL != PUBKEY && ((BN_num_bits(PUBKEY->e) < 2) || (!BN_is_odd(PUBKEY->e)))) { Log(LOG_LEVEL_ERR, "The public key RSA exponent is too small or not odd"); return false; } return true; }