|
|
2ff057 |
#include "system.h"
|
|
|
2ff057 |
#include <errno.h>
|
|
|
2ff057 |
#include <sys/wait.h>
|
|
|
2ff057 |
#include <termios.h>
|
|
|
2ff057 |
|
|
|
2ff057 |
#include <popt.h>
|
|
|
2ff057 |
#include <rpm/rpmcli.h>
|
|
|
2ff057 |
#include <rpm/rpmsign.h>
|
|
|
2ff057 |
#include "cliutils.h"
|
|
|
2ff057 |
#include "debug.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
enum modes {
|
|
|
2ff057 |
MODE_NONE = 0,
|
|
|
2ff057 |
MODE_ADDSIGN = (1 << 0),
|
|
|
2ff057 |
MODE_RESIGN = (1 << 1),
|
|
|
2ff057 |
MODE_DELSIGN = (1 << 2),
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
static int mode = MODE_NONE;
|
|
|
2ff057 |
|
|
|
2ff057 |
#ifdef WITH_IMAEVM
|
|
|
2ff057 |
static int signfiles = 0, fskpass = 0;
|
|
|
2ff057 |
static char * fileSigningKey = NULL;
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
|
|
|
2ff057 |
static struct rpmSignArgs sargs = {NULL, 0, 0};
|
|
|
2ff057 |
|
|
|
2ff057 |
static struct poptOption signOptsTable[] = {
|
|
|
2ff057 |
{ "addsign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_ADDSIGN,
|
|
|
2ff057 |
N_("sign package(s)"), NULL },
|
|
|
2ff057 |
{ "resign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_RESIGN,
|
|
|
2ff057 |
N_("sign package(s) (identical to --addsign)"), NULL },
|
|
|
2ff057 |
{ "delsign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_DELSIGN,
|
|
|
2ff057 |
N_("delete package signatures"), NULL },
|
|
|
2ff057 |
#ifdef WITH_IMAEVM
|
|
|
2ff057 |
{ "signfiles", '\0', POPT_ARG_NONE, &signfiles, 0,
|
|
|
2ff057 |
N_("sign package(s) files"), NULL},
|
|
|
2ff057 |
{ "fskpath", '\0', POPT_ARG_STRING, &fileSigningKey, 0,
|
|
|
2ff057 |
N_("use file signing key <key>"),
|
|
|
2ff057 |
N_("<key>") },
|
|
|
2ff057 |
{ "fskpass", '\0', POPT_ARG_NONE, &fskpass, 0,
|
|
|
2ff057 |
N_("prompt for file signing key password"), NULL},
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
POPT_TABLEEND
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
static struct poptOption optionsTable[] = {
|
|
|
2ff057 |
{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, signOptsTable, 0,
|
|
|
2ff057 |
N_("Signature options:"), NULL },
|
|
|
2ff057 |
{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
|
|
|
2ff057 |
N_("Common options for all rpm modes and executables:"), NULL },
|
|
|
2ff057 |
|
|
|
2ff057 |
POPT_AUTOALIAS
|
|
|
2ff057 |
POPT_AUTOHELP
|
|
|
2ff057 |
POPT_TABLEEND
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
#ifdef WITH_IMAEVM
|
|
|
2ff057 |
static char *get_fskpass(void)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
struct termios flags, tmp_flags;
|
|
|
2ff057 |
int passlen = 64;
|
|
|
2ff057 |
char *password = xmalloc(passlen);
|
|
|
2ff057 |
char *pwd = NULL;
|
|
|
2ff057 |
|
|
|
2ff057 |
tcgetattr(fileno(stdin), &flags);
|
|
|
2ff057 |
tmp_flags = flags;
|
|
|
2ff057 |
tmp_flags.c_lflag &= ~ECHO;
|
|
|
2ff057 |
tmp_flags.c_lflag |= ECHONL;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (tcsetattr(fileno(stdin), TCSANOW, &tmp_flags) != 0) {
|
|
|
2ff057 |
perror("tcsetattr");
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
printf("PEM password: ");
|
|
|
2ff057 |
pwd = fgets(password, passlen, stdin);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (tcsetattr(fileno(stdin), TCSANOW, &flags) != 0) {
|
|
|
2ff057 |
perror("tcsetattr");
|
|
|
2ff057 |
pwd = NULL;
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
exit:
|
|
|
2ff057 |
if (pwd)
|
|
|
2ff057 |
pwd[strlen(pwd) - 1] = '\0'; /* remove newline */
|
|
|
2ff057 |
else
|
|
|
2ff057 |
free(password);
|
|
|
2ff057 |
return pwd;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
|
|
|
2ff057 |
/* TODO: permit overriding macro setup on the command line */
|
|
|
2ff057 |
static int doSign(poptContext optCon, struct rpmSignArgs *sargs)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
int rc = EXIT_FAILURE;
|
|
|
2ff057 |
char * name = rpmExpand("%{?_gpg_name}", NULL);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (rstreq(name, "")) {
|
|
|
2ff057 |
fprintf(stderr, _("You must set \"%%_gpg_name\" in your macro file\n"));
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
#ifdef WITH_IMAEVM
|
|
|
2ff057 |
if (fileSigningKey) {
|
|
|
2ff057 |
rpmPushMacro(NULL, "_file_signing_key", NULL, fileSigningKey, RMIL_GLOBAL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (signfiles) {
|
|
|
2ff057 |
char *fileSigningKeyPassword = NULL;
|
|
|
2ff057 |
char *key = rpmExpand("%{?_file_signing_key}", NULL);
|
|
|
2ff057 |
if (rstreq(key, "")) {
|
|
|
2ff057 |
fprintf(stderr, _("You must set \"%%_file_signing_key\" in your macro file or on the command line with --fskpath\n"));
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (fskpass) {
|
|
|
2ff057 |
fileSigningKeyPassword = get_fskpass();
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (fileSigningKeyPassword) {
|
|
|
2ff057 |
rpmPushMacro(NULL, "_file_signing_key_password", NULL,
|
|
|
2ff057 |
fileSigningKeyPassword, RMIL_CMDLINE);
|
|
|
2ff057 |
memset(fileSigningKeyPassword, 0, strlen(fileSigningKeyPassword));
|
|
|
2ff057 |
free(fileSigningKeyPassword);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
sargs->signfiles = 1;
|
|
|
2ff057 |
free(key);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
|
|
|
2ff057 |
const char *arg;
|
|
|
2ff057 |
rc = 0;
|
|
|
2ff057 |
while ((arg = poptGetArg(optCon)) != NULL) {
|
|
Panu Matilainen |
4f16af |
if (rpmPkgSign(arg, sargs) < 0)
|
|
Panu Matilainen |
4f16af |
rc++;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
exit:
|
|
|
2ff057 |
free(name);
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
int main(int argc, char *argv[])
|
|
|
2ff057 |
{
|
|
|
2ff057 |
int ec = EXIT_FAILURE;
|
|
|
2ff057 |
poptContext optCon = NULL;
|
|
|
2ff057 |
const char *arg;
|
|
|
2ff057 |
|
|
|
2ff057 |
xsetprogname(argv[0]); /* Portability call -- see system.h */
|
|
|
2ff057 |
|
|
|
2ff057 |
optCon = rpmcliInit(argc, argv, optionsTable);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (argc <= 1) {
|
|
|
2ff057 |
printUsage(optCon, stderr, 0);
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (poptPeekArg(optCon) == NULL) {
|
|
|
2ff057 |
argerror(_("no arguments given"));
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
#ifdef WITH_IMAEVM
|
|
|
2ff057 |
if (fileSigningKey && !signfiles) {
|
|
|
2ff057 |
argerror(_("--fskpath may only be specified when signing files"));
|
|
|
2ff057 |
}
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
|
|
|
2ff057 |
switch (mode) {
|
|
|
2ff057 |
case MODE_ADDSIGN:
|
|
|
2ff057 |
case MODE_RESIGN:
|
|
|
2ff057 |
ec = doSign(optCon, &sargs);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case MODE_DELSIGN:
|
|
|
2ff057 |
ec = 0;
|
|
|
2ff057 |
while ((arg = poptGetArg(optCon)) != NULL) {
|
|
Panu Matilainen |
4f16af |
if (rpmPkgDelSign(arg, &sargs) < 0)
|
|
Panu Matilainen |
4f16af |
ec++;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case MODE_NONE:
|
|
|
2ff057 |
printUsage(optCon, stderr, 0);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
argerror(_("only one major mode may be specified"));
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
exit:
|
|
|
2ff057 |
rpmcliFini(optCon);
|
|
Panu Matilainen |
4f16af |
return RETVAL(ec);
|
|
|
2ff057 |
}
|