rpm
4.10.0
|
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 }