diff options
Diffstat (limited to 'sbin/decryptcore/decryptcore.c')
-rw-r--r-- | sbin/decryptcore/decryptcore.c | 58 |
1 files changed, 36 insertions, 22 deletions
diff --git a/sbin/decryptcore/decryptcore.c b/sbin/decryptcore/decryptcore.c index 1ca4eaf25d3f..0f054d33502d 100644 --- a/sbin/decryptcore/decryptcore.c +++ b/sbin/decryptcore/decryptcore.c @@ -55,8 +55,8 @@ usage(void) { pjdlog_exitx(1, - "usage: decryptcore [-Lv] -p privatekeyfile -k keyfile -e encryptedcore -c core\n" - " decryptcore [-Lv] [-d crashdir] -p privatekeyfile -n dumpnr"); + "usage: decryptcore [-fLv] -p privatekeyfile -k keyfile -e encryptedcore -c core\n" + " decryptcore [-fLv] [-d crashdir] -p privatekeyfile -n dumpnr"); } static int @@ -115,8 +115,8 @@ failed: } static bool -decrypt(const char *privkeyfile, const char *keyfile, const char *input, - const char *output) +decrypt(int ofd, const char *privkeyfile, const char *keyfile, + const char *input) { uint8_t buf[KERNELDUMP_BUFFER_SIZE], key[KERNELDUMP_KEY_MAX_SIZE]; EVP_CIPHER_CTX ctx; @@ -124,14 +124,14 @@ decrypt(const char *privkeyfile, const char *keyfile, const char *input, FILE *fp; struct kerneldumpkey *kdk; RSA *privkey; - int ifd, kfd, ofd, olen, privkeysize; + int ifd, kfd, olen, privkeysize; ssize_t bytes; pid_t pid; + PJDLOG_ASSERT(ofd >= 0); PJDLOG_ASSERT(privkeyfile != NULL); PJDLOG_ASSERT(keyfile != NULL); PJDLOG_ASSERT(input != NULL); - PJDLOG_ASSERT(output != NULL); privkey = NULL; @@ -142,11 +142,14 @@ decrypt(const char *privkeyfile, const char *keyfile, const char *input, pid = fork(); if (pid == -1) { pjdlog_errno(LOG_ERR, "Unable to create child process"); + close(ofd); return (false); } - if (pid > 0) + if (pid > 0) { + close(ofd); return (wait_for_process(pid) == 0); + } kfd = open(keyfile, O_RDONLY); if (kfd == -1) { @@ -158,11 +161,6 @@ decrypt(const char *privkeyfile, const char *keyfile, const char *input, pjdlog_errno(LOG_ERR, "Unable to open %s", input); goto failed; } - ofd = open(output, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (ofd == -1) { - pjdlog_errno(LOG_ERR, "Unable to open %s", output); - goto failed; - } fp = fopen(privkeyfile, "r"); if (fp == NULL) { pjdlog_errno(LOG_ERR, "Unable to open %s", privkeyfile); @@ -247,8 +245,7 @@ decrypt(const char *privkeyfile, const char *keyfile, const char *input, } if (olen > 0 && write(ofd, buf, olen) != olen) { - pjdlog_errno(LOG_ERR, "Unable to write data to %s", - output); + pjdlog_errno(LOG_ERR, "Unable to write core"); goto failed; } } while (bytes > 0); @@ -269,9 +266,11 @@ main(int argc, char **argv) { char core[PATH_MAX], encryptedcore[PATH_MAX], keyfile[PATH_MAX]; const char *crashdir, *dumpnr, *privatekey; - int ch, debug; + int ch, debug, error, ofd; size_t ii; - bool usesyslog; + bool force, usesyslog; + + error = 1; pjdlog_init(PJDLOG_MODE_STD); pjdlog_prefix_set("(decryptcore) "); @@ -281,10 +280,11 @@ main(int argc, char **argv) crashdir = NULL; dumpnr = NULL; *encryptedcore = '\0'; + force = false; *keyfile = '\0'; privatekey = NULL; usesyslog = false; - while ((ch = getopt(argc, argv, "Lc:d:e:k:n:p:v")) != -1) { + while ((ch = getopt(argc, argv, "Lc:d:e:fk:n:p:v")) != -1) { switch (ch) { case 'L': usesyslog = true; @@ -302,6 +302,9 @@ main(int argc, char **argv) pjdlog_exitx(1, "Encrypted core file path is too long."); } break; + case 'f': + force = true; + break; case 'k': if (strlcpy(keyfile, optarg, sizeof(keyfile)) >= sizeof(keyfile)) { @@ -361,13 +364,24 @@ main(int argc, char **argv) pjdlog_mode_set(PJDLOG_MODE_SYSLOG); pjdlog_debug_set(debug); - if (!decrypt(privatekey, keyfile, encryptedcore, core)) { + if (force && unlink(core) == -1 && errno != ENOENT) { + pjdlog_errno(LOG_ERR, "Unable to remove old core"); + goto out; + } + ofd = open(core, O_WRONLY | O_CREAT | O_EXCL, 0600); + if (ofd == -1) { + pjdlog_errno(LOG_ERR, "Unable to open %s", core); + goto out; + } + + if (!decrypt(ofd, privatekey, keyfile, encryptedcore)) { if (unlink(core) == -1 && errno != ENOENT) - pjdlog_exit(1, "Unable to remove core"); - exit(1); + pjdlog_errno(LOG_ERR, "Unable to remove core"); + goto out; } + error = 0; +out: pjdlog_fini(); - - exit(0); + exit(error); } |