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 \
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
@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
# 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/
--- /dev/null
+#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;
+}