Skip to content

Commit

Permalink
Allow gpg to get passphrase by itself.
Browse files Browse the repository at this point in the history
Remove rpm asking for passphrase and then passing this passphrase
to gpg via file descriptor (--passphrase-fd) but provide gpg with
access to unredirected stdin to get passphrase directly from user.

Remove also macro %__gpg_check_password_cmd because in this new signing
scheme has no sense. rpm doesn't handle passphrase in any way,
everything is done in gpg including checking of passphrase.

We did this modification because of changes in gpg behavior. Since
gpg-2.1 option "--passphrase-fd" doesn't work by default, only when
it is explicitly allowed in gpg.conf. (rhbz:#1228234)
  • Loading branch information
Lubos Kardos committed Jun 10, 2015
1 parent 6a8924b commit 0bce5fc
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 142 deletions.
4 changes: 1 addition & 3 deletions macros.in
Original file line number Diff line number Diff line change
Expand Up @@ -538,11 +538,9 @@ package or when debugging this package.\
# Macro(s) to hold the arguments passed to GPG/PGP for package
# signing and verification.
#
%__gpg_check_password_cmd %{__gpg} \
gpg --batch --no-verbose --passphrase-fd 3 -u "%{_gpg_name}" -so -

%__gpg_sign_cmd %{__gpg} \
gpg --batch --no-verbose --no-armor --passphrase-fd 3 \
gpg --no-verbose --no-armor \
%{?_gpg_digest_algo:--digest-algo %{_gpg_digest_algo}} \
--no-secmem-warning \
-u "%{_gpg_name}" -sbo %{__signature_filename} %{__plaintext_filename}
Expand Down
9 changes: 4 additions & 5 deletions python/rpmsmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,18 @@ static char rpms__doc__[] =
static PyObject * addSign(PyObject * self, PyObject * args, PyObject *kwds)
{
const char *path = NULL;
const char *passPhrase = NULL;
char * kwlist[] = { "path", "passPhrase", "keyid", "hashalgo", NULL };
char * kwlist[] = { "path", "keyid", "hashalgo", NULL };
struct rpmSignArgs sig, *sigp = NULL;

memset(&sig, 0, sizeof(sig));
if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|si", kwlist,
&path, &passPhrase, &sig.keyid, &sig.hashalgo))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|si", kwlist,
&path, &sig.keyid, &sig.hashalgo))
return NULL;

if (sig.keyid || sig.hashalgo)
sigp = &sig;

return PyBool_FromLong(rpmPkgSign(path, sigp, passPhrase) == 0);
return PyBool_FromLong(rpmPkgSign(path, sigp) == 0);
}

static PyObject * delSign(PyObject * self, PyObject * args, PyObject *kwds)
Expand Down
82 changes: 4 additions & 78 deletions rpmsign.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,72 +41,6 @@ static struct poptOption optionsTable[] = {
POPT_TABLEEND
};

static int checkPassPhrase(const char * passPhrase)
{
int passPhrasePipe[2];
int pid, status;
int rc = -1;
int xx;

if (passPhrase == NULL)
return -1;

passPhrasePipe[0] = passPhrasePipe[1] = 0;
if (pipe(passPhrasePipe))
return -1;

pid = fork();
if (pid < 0) {
close(passPhrasePipe[0]);
close(passPhrasePipe[1]);
return -1;
}

if (pid == 0) {
char * cmd, * gpg_path;
char *const *av;
int fdno;

close(STDIN_FILENO);
close(STDOUT_FILENO);
close(passPhrasePipe[1]);
if ((fdno = open("/dev/null", O_RDONLY)) != STDIN_FILENO) {
xx = dup2(fdno, STDIN_FILENO);
close(fdno);
}
if ((fdno = open("/dev/null", O_WRONLY)) != STDOUT_FILENO) {
xx = dup2(fdno, STDOUT_FILENO);
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 (xx >= 0 && rc == 0) {
rc = execve(av[0], av+1, environ);
fprintf(stderr, _("Could not exec %s: %s\n"), "gpg",
strerror(errno));
}
_exit(EXIT_FAILURE);
}

close(passPhrasePipe[0]);
xx = write(passPhrasePipe[1], passPhrase, strlen(passPhrase));
xx = write(passPhrasePipe[1], "\n", 1);
close(passPhrasePipe[1]);

if (xx >= 0 && waitpid(pid, &status, 0) >= 0)
rc = (WIFEXITED(status) && WEXITSTATUS(status) == 0) ? 0 : 1;

return rc;
}

/* TODO: permit overriding macro setup on the command line */
static int doSign(poptContext optCon)
{
Expand All @@ -119,18 +53,10 @@ static int doSign(poptContext optCon)
goto exit;
}

/* XXX FIXME: eliminate obsolete getpass() usage */
passPhrase = getpass(_("Enter pass phrase: "));
passPhrase = (passPhrase != NULL) ? rstrdup(passPhrase) : NULL;
if (checkPassPhrase(passPhrase) == 0) {
const char *arg;
fprintf(stderr, _("Pass phrase is good.\n"));
rc = 0;
while ((arg = poptGetArg(optCon)) != NULL) {
rc += rpmPkgSign(arg, NULL, passPhrase);
}
} else {
fprintf(stderr, _("Pass phrase check failed or gpg key expired\n"));
const char *arg;
rc = 0;
while ((arg = poptGetArg(optCon)) != NULL) {
rc += rpmPkgSign(arg, NULL);
}

exit:
Expand Down
67 changes: 13 additions & 54 deletions sign/rpmgensig.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,9 @@ static int putSignature(Header sigh, int ishdr, uint8_t *pkt, size_t pktlen)
return rc;
}

static int runGPG(sigTarget sigt, const char *sigfile, const char * passPhrase)
static int runGPG(sigTarget sigt, const char *sigfile)
{
int pid = 0, status;
int inpipe[2];
FILE * fpipe = NULL;
FD_t fnamedPipe = NULL;
char *namedPipeName = NULL;
unsigned char buf[BUFSIZ];
Expand All @@ -258,12 +256,6 @@ static int runGPG(sigTarget sigt, const char *sigfile, const char * passPhrase)
rpm_loff_t size;
int rc = 1; /* assume failure */

inpipe[0] = inpipe[1] = 0;
if (pipe(inpipe) < 0) {
rpmlog(RPMLOG_ERR, _("Couldn't create pipe for signing: %m"));
goto exit;
}

namedPipeName = mkTempFifo();

addMacro(NULL, "__plaintext_filename", NULL, namedPipeName, -1);
Expand All @@ -274,9 +266,6 @@ static int runGPG(sigTarget sigt, const char *sigfile, const char * passPhrase)
char *cmd = NULL;
const char *gpg_path = rpmExpand("%{?_gpg_path}", NULL);

(void) dup2(inpipe[0], 3);
(void) close(inpipe[1]);

if (gpg_path && *gpg_path != '\0')
(void) setenv("GNUPGHOME", gpg_path, 1);
(void) setenv("LC_ALL", "C", 1);
Expand All @@ -295,23 +284,6 @@ static int runGPG(sigTarget sigt, const char *sigfile, const char * passPhrase)
delMacro(NULL, "__plaintext_filename");
delMacro(NULL, "__signature_filename");

(void) close(inpipe[0]);
inpipe[0] = 0;

fpipe = fdopen(inpipe[1], "w");
if (!fpipe) {
rpmlog(RPMLOG_ERR, _("fdopen failed\n"));
goto exit;
}
inpipe[1] = 0;

if (fprintf(fpipe, "%s\n", (passPhrase ? passPhrase : "")) < 0) {
rpmlog(RPMLOG_ERR, _("Could not write to pipe\n"));
goto exit;
}
(void) fclose(fpipe);
fpipe = NULL;

fnamedPipe = Fopen(namedPipeName, "w");
if (!fnamedPipe) {
rpmlog(RPMLOG_ERR, _("Fopen failed\n"));
Expand Down Expand Up @@ -352,14 +324,6 @@ static int runGPG(sigTarget sigt, const char *sigfile, const char * passPhrase)
}

exit:
if (fpipe)
fclose(fpipe);

if (inpipe[0])
close(inpipe[0]);

if (inpipe[1])
close(inpipe[1]);

if (fnamedPipe)
Fclose(fnamedPipe);
Expand All @@ -383,16 +347,15 @@ static int runGPG(sigTarget sigt, const char *sigfile, const char * passPhrase)
* @param passPhrase private key pass phrase
* @return 0 on success, 1 on failure
*/
static int makeGPGSignature(Header sigh, int ishdr, sigTarget sigt,
const char * passPhrase)
static int makeGPGSignature(Header sigh, int ishdr, sigTarget sigt)
{
char * sigfile = rstrscat(NULL, sigt->fileName, ".sig", NULL);
struct stat st;
uint8_t * pkt = NULL;
size_t pktlen = 0;
int rc = 1; /* assume failure */

if (runGPG(sigt, sigfile, passPhrase))
if (runGPG(sigt, sigfile))
goto exit;

if (stat(sigfile, &st)) {
Expand Down Expand Up @@ -431,16 +394,15 @@ static int makeGPGSignature(Header sigh, int ishdr, sigTarget sigt,
return rc;
}

static int rpmGenSignature(Header sigh, sigTarget sigt1, sigTarget sigt2,
const char * passPhrase)
static int rpmGenSignature(Header sigh, sigTarget sigt1, sigTarget sigt2)
{
int ret;

ret = makeGPGSignature(sigh, 0, sigt1, passPhrase);
ret = makeGPGSignature(sigh, 0, sigt1);
if (ret)
goto exit;

ret = makeGPGSignature(sigh, 1, sigt2, passPhrase);
ret = makeGPGSignature(sigh, 1, sigt2);
if (ret)
goto exit;
exit:
Expand Down Expand Up @@ -486,8 +448,7 @@ static int sameSignature(rpmTagVal sigtag, Header h1, Header h2)
return (rc == 0);
}

static int replaceSignature(Header sigh, sigTarget sigt1, sigTarget sigt2,
const char *passPhrase)
static int replaceSignature(Header sigh, sigTarget sigt1, sigTarget sigt2)
{
/* Grab a copy of the header so we can compare the result */
Header oldsigh = headerCopy(sigh);
Expand All @@ -500,7 +461,7 @@ static int replaceSignature(Header sigh, sigTarget sigt1, sigTarget sigt2,
* rpmGenSignature() internals parse the actual signing result and
* adds appropriate tags for DSA/RSA.
*/
if (rpmGenSignature(sigh, sigt1, sigt2, passPhrase) == 0) {
if (rpmGenSignature(sigh, sigt1, sigt2) == 0) {
/* Lets see what we got and whether its the same signature as before */
rpmTagVal sigtag = headerIsEntry(sigh, RPMSIGTAG_DSA) ?
RPMSIGTAG_DSA : RPMSIGTAG_RSA;
Expand All @@ -517,10 +478,9 @@ static int replaceSignature(Header sigh, sigTarget sigt1, sigTarget sigt2,
* Create/modify elements in signature header.
* @param rpm path to package
* @param deleting adding or deleting signature?
* @param passPhrase passPhrase (ignored when deleting)
* @return 0 on success, -1 on error
*/
static int rpmSign(const char *rpm, int deleting, const char *passPhrase)
static int rpmSign(const char *rpm, int deleting)
{
FD_t fd = NULL;
FD_t ofd = NULL;
Expand Down Expand Up @@ -605,7 +565,7 @@ static int rpmSign(const char *rpm, int deleting, const char *passPhrase)
sigt2 = sigt1;
sigt2.size = headerSizeof(h, HEADER_MAGIC_YES);

res = replaceSignature(sigh, &sigt1, &sigt2, passPhrase);
res = replaceSignature(sigh, &sigt1, &sigt2);
if (res != 0) {
if (res == 1) {
rpmlog(RPMLOG_WARNING,
Expand Down Expand Up @@ -722,8 +682,7 @@ static int rpmSign(const char *rpm, int deleting, const char *passPhrase)
return res;
}

int rpmPkgSign(const char *path,
const struct rpmSignArgs * args, const char *passPhrase)
int rpmPkgSign(const char *path, const struct rpmSignArgs * args)
{
int rc;

Expand All @@ -739,7 +698,7 @@ int rpmPkgSign(const char *path,
}
}

rc = rpmSign(path, 0, passPhrase);
rc = rpmSign(path, 0);

if (args) {
if (args->hashalgo) {
Expand All @@ -755,5 +714,5 @@ int rpmPkgSign(const char *path,

int rpmPkgDelSign(const char *path)
{
return rpmSign(path, 1, NULL);
return rpmSign(path, 1);
}
3 changes: 1 addition & 2 deletions sign/rpmsign.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ struct rpmSignArgs {
* @param passPhrase passphrase for the signing key
* @return 0 on success
*/
int rpmPkgSign(const char *path,
const struct rpmSignArgs * args, const char *passPhrase);
int rpmPkgSign(const char *path, const struct rpmSignArgs * args);

/** \ingroup rpmsign
* Delete signature(s) from a package
Expand Down

0 comments on commit 0bce5fc

Please sign in to comment.