Skip to content

Commit

Permalink
Set the exit value when running cf-key
Browse files Browse the repository at this point in the history
When running cf-key to generate new keys, set the exit value of the
program to be 0 on success and 1 on failure. This makes it easier to
catch errors during setup of a new machine.

Change the default behavior of the program to not write anything to stdout,
opting to use the Log() function which can write to stdout and will also
allow output to be sent to syslog.

Add a --inform option to set the global log level to LOG_LEVEL_INFO.

Change the permissions of the randseed file to 600 and catch the exception
if the chmod call fails.
  • Loading branch information
skreuzer committed Aug 5, 2017
1 parent 0898031 commit e26a943
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 19 deletions.
40 changes: 25 additions & 15 deletions cf-key/cf-key-functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ int RemoveKeys(const char *input, bool must_be_coherent)
return -1;
}

void KeepKeyPromises(const char *public_key_file, const char *private_key_file)
bool KeepKeyPromises(const char *public_key_file, const char *private_key_file)
{
#ifdef OPENSSL_NO_DEPRECATED
RSA *pair = RSA_new();
Expand All @@ -332,17 +332,17 @@ void KeepKeyPromises(const char *public_key_file, const char *private_key_file)

if (stat(public_key_file, &statbuf) != -1)
{
printf("A key file already exists at %s\n", public_key_file);
return;
Log(LOG_LEVEL_ERR, "A key file already exists at %s", public_key_file);
return false;
}

if (stat(private_key_file, &statbuf) != -1)
{
printf("A key file already exists at %s\n", private_key_file);
return;
Log(LOG_LEVEL_ERR, "A key file already exists at %s", private_key_file);
return false;
}

printf("Making a key pair for CFEngine, please wait, this could take a minute...\n");
Log(LOG_LEVEL_INFO, "Making a key pair for CFEngine, please wait, this could take a minute...");

#ifdef OPENSSL_NO_DEPRECATED
BN_set_word(rsa_bignum, RSA_F4);
Expand All @@ -356,22 +356,22 @@ void KeepKeyPromises(const char *public_key_file, const char *private_key_file)
{
Log(LOG_LEVEL_ERR, "Unable to generate cryptographic key (RSA_generate_key: %s)",
CryptoLastErrorString());
return;
return false;
}

fd = safe_open(private_key_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);

if (fd < 0)
{
Log(LOG_LEVEL_ERR, "Couldn't open private key file '%s' (open: %s)", private_key_file, GetErrorStr());
return;
return false;
}

if ((fp = fdopen(fd, "w")) == NULL)
{
Log(LOG_LEVEL_ERR, "Error while writing private key file '%s' (fdopen: %s)", private_key_file, GetErrorStr());
close(fd);
return;
return false;
}

Log(LOG_LEVEL_VERBOSE, "Writing private key to '%s'", private_key_file);
Expand All @@ -382,7 +382,7 @@ void KeepKeyPromises(const char *public_key_file, const char *private_key_file)
Log(LOG_LEVEL_ERR,
"Couldn't write private key. (PEM_write_RSAPrivateKey: %s)",
CryptoLastErrorString());
return;
return false;
}

fclose(fp);
Expand All @@ -393,14 +393,14 @@ void KeepKeyPromises(const char *public_key_file, const char *private_key_file)
{
Log(LOG_LEVEL_ERR, "Couldn't open public key file '%s' (open: %s)",
public_key_file, GetErrorStr());
return;
return false;
}

if ((fp = fdopen(fd, "w")) == NULL)
{
Log(LOG_LEVEL_ERR, "Error while writing public key file '%s' (fdopen: %s)", public_key_file, GetErrorStr());
close(fd);
return;
return false;
}

Log(LOG_LEVEL_VERBOSE, "Writing public key to file '%s'", public_key_file);
Expand All @@ -410,20 +410,30 @@ void KeepKeyPromises(const char *public_key_file, const char *private_key_file)
Log(LOG_LEVEL_ERR,
"Unable to write public key. (PEM_write_RSAPublicKey: %s)",
CryptoLastErrorString());
return;
return false;
}

fclose(fp);

snprintf(vbuff, CF_BUFSIZE, "%s%crandseed", GetWorkDir(), FILE_SEPARATOR);
Log(LOG_LEVEL_VERBOSE, "Using '%s' for randseed", vbuff);

if (RAND_write_file(vbuff) != 1024)
{
Log(LOG_LEVEL_ERR, "Unable to write randseed");
unlink(vbuff); /* randseed isn't safe to use */
return;
return false;
}

if (chmod(vbuff, 0600) != 0)
{
Log(LOG_LEVEL_ERR,
"Unable to set permissions on '%s' (chmod: %s)",
vbuff, GetErrorStr());
return false;
}

chmod(vbuff, 0644);
return true;
}


Expand Down
2 changes: 1 addition & 1 deletion cf-key/cf-key-functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ bool ShowHost(const char *hostkey, const char *address,
bool incoming, const KeyHostSeen *quality, void *ctx);
void ShowLastSeenHosts();
int RemoveKeys(const char *input, bool must_be_coherent);
void KeepKeyPromises(const char *public_key_file, const char *private_key_file);
bool KeepKeyPromises(const char *public_key_file, const char *private_key_file);
int ForceKeyRemoval(const char *key);
int ForceIpAddressRemoval(const char *ip);

Expand Down
13 changes: 10 additions & 3 deletions cf-key/cf-key.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ static const char *const CF_KEY_MANPAGE_LONG_DESCRIPTION =
static const struct option OPTIONS[] =
{
{"help", no_argument, 0, 'h'},
{"inform", no_argument, 0, 'I'},
{"debug", no_argument, 0, 'd'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
Expand All @@ -86,6 +87,7 @@ static const struct option OPTIONS[] =
static const char *const HINTS[] =
{
"Print the help message",
"Print basic information about key generation",
"Enable debugging output",
"Output verbose information about the behaviour of the agent",
"Output the version of the software",
Expand Down Expand Up @@ -217,13 +219,14 @@ int main(int argc, char *argv[])
private_key_file = PrivateKeyFile(GetWorkDir());
}

KeepKeyPromises(public_key_file, private_key_file);
bool ret = KeepKeyPromises(public_key_file, private_key_file);

free(public_key_file);
free(private_key_file);

GenericAgentFinalize(ctx, config);
return 0;

return ret ? EXIT_SUCCESS : EXIT_FAILURE;
}

/*****************************************************************************/
Expand All @@ -236,7 +239,7 @@ static GenericAgentConfig *CheckOpts(int argc, char **argv)
int c;
GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_KEYGEN, GetTTYInteractive());

while ((c = getopt_long(argc, argv, "dvf:VMp:sr:xt:hl:C::n",
while ((c = getopt_long(argc, argv, "dvIf:VMp:sr:xt:hl:C::n",
OPTIONS, NULL))
!= -1)
{
Expand All @@ -262,6 +265,10 @@ static GenericAgentConfig *CheckOpts(int argc, char **argv)
LogSetGlobalLevel(LOG_LEVEL_VERBOSE);
break;

case 'I':
LogSetGlobalLevel(LOG_LEVEL_INFO);
break;

case 'p': /* print digest */
print_digest_arg = optarg;
break;
Expand Down

0 comments on commit e26a943

Please sign in to comment.