summaryrefslogtreecommitdiff
path: root/rpmsign.c
diff options
context:
space:
mode:
Diffstat (limited to 'rpmsign.c')
-rw-r--r--rpmsign.c168
1 files changed, 97 insertions, 71 deletions
diff --git a/rpmsign.c b/rpmsign.c
index e29864e0b..ae86f666d 100644
--- a/rpmsign.c
+++ b/rpmsign.c
@@ -1,6 +1,7 @@
#include "system.h"
#include <errno.h>
#include <sys/wait.h>
+#include <termios.h>
#include <popt.h>
#include <rpm/rpmcli.h>
@@ -8,17 +9,21 @@
#include "cliutils.h"
#include "debug.h"
-#if !defined(__GLIBC__) && !defined(__APPLE__)
-char ** environ = NULL;
-#endif
-
enum modes {
+ MODE_NONE = 0,
MODE_ADDSIGN = (1 << 0),
MODE_RESIGN = (1 << 1),
MODE_DELSIGN = (1 << 2),
};
-static int mode = 0;
+static int mode = MODE_NONE;
+
+#ifdef WITH_IMAEVM
+static int signfiles = 0, fskpass = 0;
+static char * fileSigningKey = NULL;
+#endif
+
+static struct rpmSignArgs sargs = {NULL, 0, 0};
static struct poptOption signOptsTable[] = {
{ "addsign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_ADDSIGN,
@@ -27,6 +32,15 @@ static struct poptOption signOptsTable[] = {
N_("sign package(s) (identical to --addsign)"), NULL },
{ "delsign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_DELSIGN,
N_("delete package signatures"), NULL },
+#ifdef WITH_IMAEVM
+ { "signfiles", '\0', POPT_ARG_NONE, &signfiles, 0,
+ N_("sign package(s) files"), NULL},
+ { "fskpath", '\0', POPT_ARG_STRING, &fileSigningKey, 0,
+ N_("use file signing key <key>"),
+ N_("<key>") },
+ { "fskpass", '\0', POPT_ARG_NONE, &fskpass, 0,
+ N_("prompt for file signing key password"), NULL},
+#endif
POPT_TABLEEND
};
@@ -41,67 +55,46 @@ static struct poptOption optionsTable[] = {
POPT_TABLEEND
};
-static int checkPassPhrase(const char * passPhrase)
+#ifdef WITH_IMAEVM
+static char *get_fskpass(void)
{
- int passPhrasePipe[2];
- int pid, status;
- int rc;
- int xx;
-
- if (passPhrase == NULL)
- return -1;
-
- passPhrasePipe[0] = passPhrasePipe[1] = 0;
- xx = pipe(passPhrasePipe);
- if (!(pid = fork())) {
- char * cmd, * gpg_path;
- char *const *av;
- int fdno;
-
- xx = close(STDIN_FILENO);
- xx = close(STDOUT_FILENO);
- xx = close(passPhrasePipe[1]);
- if ((fdno = open("/dev/null", O_RDONLY)) != STDIN_FILENO) {
- xx = dup2(fdno, STDIN_FILENO);
- xx = close(fdno);
- }
- if ((fdno = open("/dev/null", O_WRONLY)) != STDOUT_FILENO) {
- xx = dup2(fdno, STDOUT_FILENO);
- xx = close(fdno);
- }
- xx = dup2(passPhrasePipe[0], 3);
-
- unsetenv("MALLOC_CHECK_");
- gpg_path = rpmExpand("%{?_gpg_path}", NULL);
-
- if (!rstreq(gpg_path, ""))
- setenv("GNUPGHOME", gpg_path, 1);
-
- cmd = rpmExpand("%{?__gpg_check_password_cmd}", NULL);
- rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
- if (!rc)
- rc = execve(av[0], av+1, environ);
-
- fprintf(stderr, _("Could not exec %s: %s\n"), "gpg",
- strerror(errno));
- _exit(EXIT_FAILURE);
+ struct termios flags, tmp_flags;
+ int passlen = 64;
+ char *password = xmalloc(passlen);
+ char *pwd = NULL;
+
+ tcgetattr(fileno(stdin), &flags);
+ tmp_flags = flags;
+ tmp_flags.c_lflag &= ~ECHO;
+ tmp_flags.c_lflag |= ECHONL;
+
+ if (tcsetattr(fileno(stdin), TCSANOW, &tmp_flags) != 0) {
+ perror("tcsetattr");
+ goto exit;
}
- xx = close(passPhrasePipe[0]);
- xx = write(passPhrasePipe[1], passPhrase, strlen(passPhrase));
- xx = write(passPhrasePipe[1], "\n", 1);
- xx = close(passPhrasePipe[1]);
+ printf("PEM password: ");
+ pwd = fgets(password, passlen, stdin);
- (void) waitpid(pid, &status, 0);
+ if (tcsetattr(fileno(stdin), TCSANOW, &flags) != 0) {
+ perror("tcsetattr");
+ pwd = NULL;
+ goto exit;
+ }
- return ((WIFEXITED(status) && WEXITSTATUS(status) == 0)) ? 0 : 1;
+exit:
+ if (pwd)
+ pwd[strlen(pwd) - 1] = '\0'; /* remove newline */
+ else
+ free(password);
+ return pwd;
}
+#endif
/* TODO: permit overriding macro setup on the command line */
-static int doSign(poptContext optCon)
+static int doSign(poptContext optCon, struct rpmSignArgs *sargs)
{
int rc = EXIT_FAILURE;
- char * passPhrase = NULL;
char * name = rpmExpand("%{?_gpg_name}", NULL);
if (rstreq(name, "")) {
@@ -109,22 +102,42 @@ static int doSign(poptContext optCon)
goto exit;
}
- /* XXX FIXME: eliminate obsolete getpass() usage */
- passPhrase = getpass(_("Enter pass phrase: "));
- passPhrase = (passPhrase != NULL) ? rstrdup(passPhrase) : NULL;
- if (checkPassPhrase(passPhrase) == 0) {
- const char *arg;
- fprintf(stderr, _("Pass phrase is good.\n"));
- rc = 0;
- while ((arg = poptGetArg(optCon)) != NULL) {
- rc += rpmPkgSign(arg, NULL, passPhrase);
+#ifdef WITH_IMAEVM
+ if (fileSigningKey) {
+ rpmPushMacro(NULL, "_file_signing_key", NULL, fileSigningKey, RMIL_GLOBAL);
+ }
+
+ if (signfiles) {
+ char *fileSigningKeyPassword = NULL;
+ char *key = rpmExpand("%{?_file_signing_key}", NULL);
+ if (rstreq(key, "")) {
+ fprintf(stderr, _("You must set \"%%_file_signing_key\" in your macro file or on the command line with --fskpath\n"));
+ goto exit;
}
- } else {
- fprintf(stderr, _("Pass phrase check failed or gpg key expired\n"));
+
+ if (fskpass) {
+ fileSigningKeyPassword = get_fskpass();
+ }
+
+ if (fileSigningKeyPassword) {
+ rpmPushMacro(NULL, "_file_signing_key_password", NULL,
+ fileSigningKeyPassword, RMIL_CMDLINE);
+ memset(fileSigningKeyPassword, 0, strlen(fileSigningKeyPassword));
+ free(fileSigningKeyPassword);
+ }
+
+ sargs->signfiles = 1;
+ free(key);
+ }
+#endif
+
+ const char *arg;
+ rc = 0;
+ while ((arg = poptGetArg(optCon)) != NULL) {
+ rc += rpmPkgSign(arg, sargs);
}
exit:
- free(passPhrase);
free(name);
return rc;
}
@@ -132,9 +145,13 @@ exit:
int main(int argc, char *argv[])
{
int ec = EXIT_FAILURE;
- poptContext optCon = rpmcliInit(argc, argv, optionsTable);
+ poptContext optCon = NULL;
const char *arg;
+ xsetprogname(argv[0]); /* Portability call -- see system.h */
+
+ optCon = rpmcliInit(argc, argv, optionsTable);
+
if (argc <= 1) {
printUsage(optCon, stderr, 0);
goto exit;
@@ -144,17 +161,26 @@ int main(int argc, char *argv[])
argerror(_("no arguments given"));
}
+#ifdef WITH_IMAEVM
+ if (fileSigningKey && !signfiles) {
+ argerror(_("--fskpath may only be specified when signing files"));
+ }
+#endif
+
switch (mode) {
case MODE_ADDSIGN:
case MODE_RESIGN:
- ec = doSign(optCon);
+ ec = doSign(optCon, &sargs);
break;
case MODE_DELSIGN:
ec = 0;
while ((arg = poptGetArg(optCon)) != NULL) {
- ec += rpmPkgDelSign(arg);
+ ec += rpmPkgDelSign(arg, &sargs);
}
break;
+ case MODE_NONE:
+ printUsage(optCon, stderr, 0);
+ break;
default:
argerror(_("only one major mode may be specified"));
break;