Add a brand new rpmsign utility for package signing
- Signing (and deleting) are different from everything else in rpm in that it needs very little of rpm's facilities. For example access to the rpmdb is not needed at all. Splitting this to a separate, small utility allows various possibilities, like severely limiting its access from SELinux POV, control of signature generation with cli arguments (the main rpm executable is already overcrowded with options). It's also the first step to allow reasonably splitting rpm signing to a separate package; not everybody needs to sign packages, yet signing support needs to drag in GPG and whatnot. - Reimplement / refactor various librpm signature generation helpers into somewhat saner internal versions.
This commit is contained in:
parent
8f75ac30fb
commit
df0b760e7e
11
Makefile.am
11
Makefile.am
|
@ -78,7 +78,7 @@ pkginclude_HEADERS += build/rpmspec.h
|
|||
rpmbindir = `echo $(bindir) | $(SED) -e s,usr/bin,bin,`
|
||||
rpmbin_PROGRAMS = rpm
|
||||
|
||||
bin_PROGRAMS = rpm2cpio rpmbuild
|
||||
bin_PROGRAMS = rpm2cpio rpmbuild rpmsign
|
||||
|
||||
rpmlibexec_PROGRAMS =
|
||||
rpmconfig_SCRIPTS = find-provides find-requires mkinstalldirs \
|
||||
|
@ -98,6 +98,12 @@ rpm_LDADD = libcliutils.la
|
|||
rpm_LDADD += build/librpmbuild.la lib/librpm.la rpmio/librpmio.la
|
||||
rpm_LDADD += @WITH_NSS_LIB@ @WITH_POPT_LIB@ @WITH_ZLIB_LIB@
|
||||
|
||||
rpmsign_SOURCES = rpmsign.c debug.h system.h
|
||||
rpmsign_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
rpmsign_LDADD = libcliutils.la
|
||||
rpmsign_LDADD += lib/librpm.la rpmio/librpmio.la
|
||||
rpmsign_LDADD += @WITH_NSS_LIB@ @WITH_POPT_LIB@ @WITH_ZLIB_LIB@
|
||||
|
||||
rpmbuild_SOURCES = rpmbuild.c debug.h system.h
|
||||
rpmbuild_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
rpmbuild_LDADD = libcliutils.la
|
||||
|
@ -191,8 +197,6 @@ install-exec-hook:
|
|||
@LN_S@ ../../bin/rpm $(DESTDIR)$(bindir)/rpmquery
|
||||
rm -f $(DESTDIR)$(bindir)/rpmverify
|
||||
@LN_S@ ../../bin/rpm $(DESTDIR)$(bindir)/rpmverify
|
||||
rm -f $(DESTDIR)$(bindir)/rpmsign
|
||||
@LN_S@ ../../bin/rpm $(DESTDIR)$(bindir)/rpmsign
|
||||
rm -f $(DESTDIR)$(bindir)/rpmdb
|
||||
@LN_S@ ../../bin/rpm $(DESTDIR)$(bindir)/rpmdb
|
||||
|
||||
|
@ -206,7 +210,6 @@ install-data-local:
|
|||
# XXX to appease distcheck we need to remove "stuff" here...
|
||||
uninstall-local:
|
||||
@rm -f $(DESTDIR)$(bindir)/rpmquery
|
||||
@rm -f $(DESTDIR)$(bindir)/rpmsign
|
||||
@rm -f $(DESTDIR)$(bindir)/rpmverify
|
||||
@rm -f $(DESTDIR)$(bindir)/rpmdb
|
||||
@rm -rf $(DESTDIR)$(rpmconfigdir)/platform/
|
||||
|
|
|
@ -6,6 +6,7 @@ cliutils.c
|
|||
rpm2cpio.c
|
||||
rpmqv.c
|
||||
rpmbuild.c
|
||||
rpmsign.c
|
||||
build/build.c
|
||||
build/expression.c
|
||||
build/files.c
|
||||
|
|
|
@ -0,0 +1,187 @@
|
|||
#include "system.h"
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <popt.h>
|
||||
#include <rpm/rpmcli.h>
|
||||
#include "cliutils.h"
|
||||
#include "debug.h"
|
||||
|
||||
#if !defined(__GLIBC__) && !defined(__APPLE__)
|
||||
char ** environ = NULL;
|
||||
#endif
|
||||
|
||||
enum modes {
|
||||
MODE_ADDSIGN = (1 << 0),
|
||||
MODE_RESIGN = (1 << 1),
|
||||
MODE_DELSIGN = (1 << 2),
|
||||
};
|
||||
|
||||
static int mode = 0;
|
||||
|
||||
static struct poptOption optionsTable[] = {
|
||||
{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
|
||||
N_("Common options for all rpm modes and executables:"), NULL },
|
||||
{ "addsign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_ADDSIGN,
|
||||
N_("sign package(s)"), NULL },
|
||||
{ "resign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_RESIGN,
|
||||
N_("sign package(s) (identical to --addsign)"), NULL },
|
||||
{ "delsign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_DELSIGN,
|
||||
N_("delete package signatures"), NULL },
|
||||
|
||||
POPT_AUTOALIAS
|
||||
POPT_AUTOHELP
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
||||
static rpmSigTag lookupSignatureType(void)
|
||||
{
|
||||
rpmSigTag rc = 0;
|
||||
|
||||
char *name = rpmExpand("%{?_signature}", NULL);
|
||||
if (!(name && *name != '\0'))
|
||||
rc = 0;
|
||||
else if (!rstrcasecmp(name, "none"))
|
||||
rc = 0;
|
||||
else if (!rstrcasecmp(name, "pgp"))
|
||||
rc = RPMSIGTAG_PGP;
|
||||
else if (!rstrcasecmp(name, "pgp5")) /* XXX legacy */
|
||||
rc = RPMSIGTAG_PGP;
|
||||
else if (!rstrcasecmp(name, "gpg"))
|
||||
rc = RPMSIGTAG_GPG;
|
||||
else
|
||||
rc = -1; /* Invalid %_signature spec in macro file */
|
||||
|
||||
name = _free(name);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int checkPassPhrase(const char * passPhrase)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
xx = close(passPhrasePipe[0]);
|
||||
xx = write(passPhrasePipe[1], passPhrase, strlen(passPhrase));
|
||||
xx = write(passPhrasePipe[1], "\n", 1);
|
||||
xx = close(passPhrasePipe[1]);
|
||||
|
||||
(void) waitpid(pid, &status, 0);
|
||||
|
||||
return ((WIFEXITED(status) && WEXITSTATUS(status) == 0)) ? 0 : 1;
|
||||
}
|
||||
|
||||
/* TODO: permit overriding macro setup on the command line */
|
||||
static int doSign(ARGV_const_t args)
|
||||
{
|
||||
int rc = EXIT_FAILURE;
|
||||
int sigTag = lookupSignatureType();
|
||||
char * passPhrase = NULL;
|
||||
char * name = rpmExpand("%{?_gpg_name}", NULL);
|
||||
|
||||
if (rstreq(name, "")) {
|
||||
fprintf(stderr, _("You must set \"%%_gpg_name\" in your macro file\n"));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (sigTag) {
|
||||
case RPMSIGTAG_PGP:
|
||||
case RPMSIGTAG_GPG:
|
||||
case RPMSIGTAG_DSA:
|
||||
case RPMSIGTAG_RSA:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, _("Invalid %%_signature spec in macro file.\n"));
|
||||
goto exit;
|
||||
break;
|
||||
}
|
||||
|
||||
/* XXX FIXME: eliminate obsolete getpass() usage */
|
||||
passPhrase = getpass(_("Enter pass phrase: "));
|
||||
passPhrase = (passPhrase != NULL) ? rstrdup(passPhrase) : NULL;
|
||||
if (checkPassPhrase(passPhrase) == 0) {
|
||||
fprintf(stderr, _("Pass phrase is good.\n"));
|
||||
rc = rpmcliSign(args, 0, sigTag, passPhrase);
|
||||
} else {
|
||||
fprintf(stderr, _("Pass phrase check failed\n"));
|
||||
}
|
||||
|
||||
exit:
|
||||
free(name);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ec = EXIT_FAILURE;
|
||||
poptContext optCon = rpmcliInit(argc, argv, optionsTable);
|
||||
ARGV_const_t args = NULL;
|
||||
|
||||
if (argc <= 1) {
|
||||
printUsage(optCon, stderr, 0);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
args = (ARGV_const_t) poptGetArgs(optCon);
|
||||
if (args == NULL) {
|
||||
argerror(_("no arguments given"));
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case MODE_ADDSIGN:
|
||||
case MODE_RESIGN:
|
||||
ec = doSign(args);
|
||||
break;
|
||||
case MODE_DELSIGN:
|
||||
ec = rpmcliSign(args, 1, 0, NULL);
|
||||
break;
|
||||
default:
|
||||
argerror(_("only one major mode may be specified"));
|
||||
break;
|
||||
}
|
||||
|
||||
exit:
|
||||
rpmcliFini(optCon);
|
||||
return ec;
|
||||
}
|
Loading…
Reference in New Issue