rpm 4.10.0

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

rpmsign.c
Go to the documentation of this file.

    00001 #include "system.h"
    00002 #include <errno.h>
    00003 #include <sys/wait.h>
    00004
    00005 #include <popt.h>
    00006 #include <rpm/rpmcli.h>
    00007 #include <rpm/rpmsign.h>
    00008 #include "cliutils.h"
    00009 #include "debug.h"
    00010
    00011 #if !defined(__GLIBC__) && !defined(__APPLE__)
    00012 char ** environ = NULL;
    00013 #endif
    00014
    00015 enum modes {
    00016     MODE_ADDSIGN = (1 << 0),
    00017     MODE_RESIGN  = (1 << 1),
    00018     MODE_DELSIGN = (1 << 2),
    00019 };
    00020
    00021 static int mode = 0;
    00022
    00023 static struct poptOption signOptsTable[] = {
    00024     { "addsign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_ADDSIGN,
    00025         N_("sign package(s)"), NULL },
    00026     { "resign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_RESIGN,
    00027         N_("sign package(s) (identical to --addsign)"), NULL },
    00028     { "delsign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_DELSIGN,
    00029         N_("delete package signatures"), NULL },
    00030     POPT_TABLEEND
    00031 };
    00032
    00033 static struct poptOption optionsTable[] = {
    00034     { NULL, '\0', POPT_ARG_INCLUDE_TABLE, signOptsTable, 0,
    00035         N_("Signature options:"), NULL },
    00036     { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
    00037         N_("Common options for all rpm modes and executables:"), NULL },
    00038
    00039     POPT_AUTOALIAS
    00040     POPT_AUTOHELP
    00041     POPT_TABLEEND
    00042 };
    00043
    00044 static int checkPassPhrase(const char * passPhrase)
    00045 {
    00046     int passPhrasePipe[2];
    00047     int pid, status;
    00048     int rc;
    00049     int xx;
    00050
    00051     if (passPhrase == NULL)
    00052         return -1;
    00053
    00054     passPhrasePipe[0] = passPhrasePipe[1] = 0;
    00055     xx = pipe(passPhrasePipe);
    00056     if (!(pid = fork())) {
    00057         char * cmd, * gpg_path;
    00058         char *const *av;
    00059         int fdno;
    00060
    00061         xx = close(STDIN_FILENO);
    00062         xx = close(STDOUT_FILENO);
    00063         xx = close(passPhrasePipe[1]);
    00064         if ((fdno = open("/dev/null", O_RDONLY)) != STDIN_FILENO) {
    00065             xx = dup2(fdno, STDIN_FILENO);
    00066             xx = close(fdno);
    00067         }
    00068         if ((fdno = open("/dev/null", O_WRONLY)) != STDOUT_FILENO) {
    00069             xx = dup2(fdno, STDOUT_FILENO);
    00070             xx = close(fdno);
    00071         }
    00072         xx = dup2(passPhrasePipe[0], 3);
    00073
    00074         unsetenv("MALLOC_CHECK_");
    00075         gpg_path = rpmExpand("%{?_gpg_path}", NULL);
    00076
    00077         if (!rstreq(gpg_path, ""))
    00078             setenv("GNUPGHOME", gpg_path, 1);
    00079
    00080         cmd = rpmExpand("%{?__gpg_check_password_cmd}", NULL);
    00081         rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
    00082         if (!rc)
    00083             rc = execve(av[0], av+1, environ);
    00084
    00085         fprintf(stderr, _("Could not exec %s: %s\n"), "gpg",
    00086                     strerror(errno));
    00087         _exit(EXIT_FAILURE);
    00088     }
    00089
    00090     xx = close(passPhrasePipe[0]);
    00091     xx = write(passPhrasePipe[1], passPhrase, strlen(passPhrase));
    00092     xx = write(passPhrasePipe[1], "\n", 1);
    00093     xx = close(passPhrasePipe[1]);
    00094
    00095     (void) waitpid(pid, &status, 0);
    00096
    00097     return ((WIFEXITED(status) && WEXITSTATUS(status) == 0)) ? 0 : 1;
    00098 }
    00099
    00100 /* TODO: permit overriding macro setup on the command line */
    00101 static int doSign(poptContext optCon)
    00102 {
    00103     int rc = EXIT_FAILURE;
    00104     char * passPhrase = NULL;
    00105     char * name = rpmExpand("%{?_gpg_name}", NULL);
    00106
    00107     if (rstreq(name, "")) {
    00108         fprintf(stderr, _("You must set \"%%_gpg_name\" in your macro file\n"));
    00109         goto exit;
    00110     }
    00111
    00112     /* XXX FIXME: eliminate obsolete getpass() usage */
    00113     passPhrase = getpass(_("Enter pass phrase: "));
    00114     passPhrase = (passPhrase != NULL) ? rstrdup(passPhrase) : NULL;
    00115     if (checkPassPhrase(passPhrase) == 0) {
    00116         const char *arg;
    00117         fprintf(stderr, _("Pass phrase is good.\n"));
    00118         rc = 0;
    00119         while ((arg = poptGetArg(optCon)) != NULL) {
    00120             rc += rpmPkgSign(arg, NULL, passPhrase);
    00121         }
    00122     } else {
    00123         fprintf(stderr, _("Pass phrase check failed or gpg key expired\n"));
    00124     }
    00125
    00126 exit:
    00127     free(passPhrase);
    00128     free(name);
    00129     return rc;
    00130 }
    00131
    00132 int main(int argc, char *argv[])
    00133 {
    00134     int ec = EXIT_FAILURE;
    00135     poptContext optCon = rpmcliInit(argc, argv, optionsTable);
    00136     const char *arg;
    00137
    00138     if (argc <= 1) {
    00139         printUsage(optCon, stderr, 0);
    00140         goto exit;
    00141     }
    00142
    00143     if (poptPeekArg(optCon) == NULL) {
    00144         argerror(_("no arguments given"));
    00145     }
    00146
    00147     switch (mode) {
    00148     case MODE_ADDSIGN:
    00149     case MODE_RESIGN:
    00150         ec = doSign(optCon);
    00151         break;
    00152     case MODE_DELSIGN:
    00153         ec = 0;
    00154         while ((arg = poptGetArg(optCon)) != NULL) {
    00155             ec += rpmPkgDelSign(arg);
    00156         }
    00157         break;
    00158     default:
    00159         argerror(_("only one major mode may be specified"));
    00160         break;
    00161     }
    00162
    00163 exit:
    00164     rpmcliFini(optCon);
    00165     return ec;
    00166 }