rpm  4.13.0
rpmsign.c
Go to the documentation of this file.
1 #include "system.h"
2 #include <errno.h>
3 #include <sys/wait.h>
4 
5 #include <popt.h>
6 #include <rpm/rpmcli.h>
7 #include <rpm/rpmsign.h>
8 #include "cliutils.h"
9 #include "lib/rpmsignfiles.h"
10 #include "debug.h"
11 
12 #if !defined(__GLIBC__) && !defined(__APPLE__)
13 char ** environ = NULL;
14 #endif
15 
16 enum modes {
17  MODE_ADDSIGN = (1 << 0),
18  MODE_RESIGN = (1 << 1),
19  MODE_DELSIGN = (1 << 2),
20 };
21 
22 static int mode = 0;
23 
24 static int signfiles = 0, fskpass = 0;
25 static char * fileSigningKey = NULL;
26 static char * fileSigningKeyPassword = NULL;
27 
28 static struct poptOption signOptsTable[] = {
29  { "addsign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_ADDSIGN,
30  N_("sign package(s)"), NULL },
31  { "resign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_RESIGN,
32  N_("sign package(s) (identical to --addsign)"), NULL },
33  { "delsign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_DELSIGN,
34  N_("delete package signatures"), NULL },
35  { "signfiles", '\0', POPT_ARG_NONE, &signfiles, 0,
36  N_("sign package(s) files"), NULL},
37  { "fskpath", '\0', POPT_ARG_STRING, &fileSigningKey, 0,
38  N_("use file signing key <key>"),
39  N_("<key>") },
40  { "fskpass", '\0', POPT_ARG_NONE, &fskpass, 0,
41  N_("prompt for file signing key password"), NULL},
42  POPT_TABLEEND
43 };
44 
45 static struct poptOption optionsTable[] = {
46  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, signOptsTable, 0,
47  N_("Signature options:"), NULL },
48  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
49  N_("Common options for all rpm modes and executables:"), NULL },
50 
51  POPT_AUTOALIAS
52  POPT_AUTOHELP
53  POPT_TABLEEND
54 };
55 
56 /* TODO: permit overriding macro setup on the command line */
57 static int doSign(poptContext optCon)
58 {
59  int rc = EXIT_FAILURE;
60  char * passPhrase = NULL;
61  char * name = rpmExpand("%{?_gpg_name}", NULL);
62  struct rpmSignArgs sig = {NULL, 0, 0};
63 
64  if (rstreq(name, "")) {
65  fprintf(stderr, _("You must set \"%%_gpg_name\" in your macro file\n"));
66  goto exit;
67  }
68 
69  if (fileSigningKey) {
70  addMacro(NULL, "_file_signing_key", NULL, fileSigningKey, RMIL_GLOBAL);
71  }
72 
73  if (signfiles) {
74  const char *key = rpmExpand("%{?_file_signing_key}", NULL);
75  if (rstreq(key, "")) {
76  fprintf(stderr, _("You must set \"$$_file_signing_key\" in your macro file or on the command line with --fskpath\n"));
77  goto exit;
78  }
79 
80  if (fskpass) {
81 #ifndef WITH_IMAEVM
82  argerror(_("--fskpass may only be specified when signing files"));
83 #else
84  fileSigningKeyPassword = get_fskpass();
85 #endif
86  }
87 
88  addMacro(NULL, "_file_signing_key_password", NULL,
89  fileSigningKeyPassword, RMIL_CMDLINE);
90  if (fileSigningKeyPassword) {
91  memset(fileSigningKeyPassword, 0, strlen(fileSigningKeyPassword));
92  free(fileSigningKeyPassword);
93  }
94 
95  sig.signfiles = 1;
96  }
97 
98  const char *arg;
99  rc = 0;
100  while ((arg = poptGetArg(optCon)) != NULL) {
101  rc += rpmPkgSign(arg, &sig);
102  }
103 
104 exit:
105  free(passPhrase);
106  free(name);
107  return rc;
108 }
109 
110 int main(int argc, char *argv[])
111 {
112  int ec = EXIT_FAILURE;
113  poptContext optCon = rpmcliInit(argc, argv, optionsTable);
114  const char *arg;
115 
116  if (argc <= 1) {
117  printUsage(optCon, stderr, 0);
118  goto exit;
119  }
120 
121  if (poptPeekArg(optCon) == NULL) {
122  argerror(_("no arguments given"));
123  }
124 
125  if (fileSigningKey && !signfiles) {
126  argerror(_("--fskpath may only be specified when signing files"));
127  }
128 
129  switch (mode) {
130  case MODE_ADDSIGN:
131  case MODE_RESIGN:
132  ec = doSign(optCon);
133  break;
134  case MODE_DELSIGN:
135  ec = 0;
136  while ((arg = poptGetArg(optCon)) != NULL) {
137  ec += rpmPkgDelSign(arg);
138  }
139  break;
140  default:
141  argerror(_("only one major mode may be specified"));
142  break;
143  }
144 
145 exit:
146  rpmcliFini(optCon);
147  return ec;
148 }
int rpmPkgSign(const char *path, const struct rpmSignArgs *args)
Sign a package.
void printUsage(poptContext con, FILE *fp, int flags)
Definition: cliutils.c:36
#define RMIL_GLOBAL
Definition: rpmmacro.h:44
poptContext rpmcliInit(int argc, char *const argv[], struct poptOption *optionsTable)
Initialize most everything needed by an rpm CLI executable context.
poptContext rpmcliFini(poptContext optCon)
Destroy most everything needed by an rpm CLI executable context.
#define _(Text)
Definition: system.h:110
static char * fileSigningKeyPassword
Definition: rpmsign.c:26
void argerror(const char *desc)
Definition: cliutils.c:19
static struct poptOption optionsTable[]
Definition: rpmsign.c:45
static struct poptOption signOptsTable[]
Definition: rpmsign.c:28
static int mode
Definition: rpmsign.c:22
static int rstreq(const char *s1, const char *s2)
Test for string equality.
Definition: rpmstring.h:113
modes
Definition: rpmbuild.c:250
static int signfiles
Definition: rpmsign.c:24
int main(int argc, char *argv[])
Definition: rpmsign.c:110
static int fskpass
Definition: rpmsign.c:24
void addMacro(rpmMacroContext mc, const char *n, const char *o, const char *b, int level)
Add macro to context.
char ** environ
Definition: rpmsign.c:13
int rpmPkgDelSign(const char *path)
Delete signature(s) from a package.
char * rpmExpand(const char *arg,...) RPM_GNUC_NULL_TERMINATED
Return (malloc&#39;ed) concatenated macro expansion(s).
static char * fileSigningKey
Definition: rpmsign.c:25
#define N_(Text)
Definition: system.h:113
#define RMIL_CMDLINE
Definition: rpmmacro.h:40
static int doSign(poptContext optCon)
Definition: rpmsign.c:57
int signfiles
Definition: rpmsign.h:14
struct poptOption rpmcliAllPoptTable[]
Popt option table for options shared by all modes and executables.