mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
* exechelp.h, exechelp.c: New. Based on code from ../sm/import.c.
* gpgsm.c (run_protect_tool) [_WIN32]: Disabled. * import.c (popen_protect_tool): Simplified by making use of gnupg_spawn_process. (parse_p12): Likewise, using gnupg_wait_process. * export.c (popen_protect_tool): Ditto. (export_p12): Ditto.
This commit is contained in:
parent
8f620c8c2c
commit
0a058ac53c
@ -1,3 +1,7 @@
|
|||||||
|
2004-12-06 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* exechelp.h, exechelp.c: New. Based on code from ../sm/import.c.
|
||||||
|
|
||||||
2004-12-03 Werner Koch <wk@g10code.com>
|
2004-12-03 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* strsep.c: Fixed copyright comments.
|
* strsep.c: Fixed copyright comments.
|
||||||
|
@ -41,6 +41,7 @@ libcommon_a_SOURCES = \
|
|||||||
iobuf.c iobuf.h \
|
iobuf.c iobuf.h \
|
||||||
ttyio.c ttyio.h \
|
ttyio.c ttyio.h \
|
||||||
asshelp.c asshelp.h \
|
asshelp.c asshelp.h \
|
||||||
|
exechelp.c exechelp.h \
|
||||||
simple-gettext.c \
|
simple-gettext.c \
|
||||||
w32reg.c \
|
w32reg.c \
|
||||||
signal.c \
|
signal.c \
|
||||||
|
230
common/exechelp.c
Normal file
230
common/exechelp.c
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
/* exechelp.c - fork and exec helpers
|
||||||
|
* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#ifdef USE_GNU_PTH
|
||||||
|
#include <pth.h>
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN32
|
||||||
|
#else
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "i18n.h"
|
||||||
|
#include "exechelp.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _POSIX_OPEN_MAX
|
||||||
|
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
|
||||||
|
#else
|
||||||
|
#define MAX_OPEN_FDS 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We have the usual problem here: Some modules are linked against pth
|
||||||
|
and some are not. However we want to use pth_fork and pth_waitpid
|
||||||
|
here. Using a weak symbol works but is not portable - we should
|
||||||
|
provide a an explicit dummy pth module instead of using the
|
||||||
|
pragma. */
|
||||||
|
#ifndef _WIN32
|
||||||
|
#pragma weak pth_fork
|
||||||
|
#pragma weak pth_waitpid
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
|
||||||
|
stdin, write the output to OUTFILE, return a new stream in
|
||||||
|
STATUSFILE for stderr and the pid of the process in PID. The
|
||||||
|
arguments for the process are expected in the NULL terminated array
|
||||||
|
ARGV. The program name itself should not be included there. if
|
||||||
|
PREEXEC is not NULL, that function will be called right before the
|
||||||
|
exec.
|
||||||
|
|
||||||
|
Returns 0 on success or an error code. */
|
||||||
|
gpg_error_t
|
||||||
|
gnupg_spawn_process (const char *pgmname, const char *argv[],
|
||||||
|
FILE *infile, FILE *outfile,
|
||||||
|
void (*preexec)(void),
|
||||||
|
FILE **statusfile, pid_t *pid)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
|
|
||||||
|
#else /* !_WIN32 */
|
||||||
|
gpg_error_t err;
|
||||||
|
int fd, fdout, rp[2];
|
||||||
|
|
||||||
|
*statusfile = NULL;
|
||||||
|
*pid = (pid_t)(-1);
|
||||||
|
fflush (infile);
|
||||||
|
rewind (infile);
|
||||||
|
fd = fileno (infile);
|
||||||
|
fdout = fileno (outfile);
|
||||||
|
if (fd == -1 || fdout == -1)
|
||||||
|
log_fatal ("no file descriptor for file passed"
|
||||||
|
" to gnupg_spawn_process: %s\n", strerror (errno) );
|
||||||
|
|
||||||
|
if (pipe (rp) == -1)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_errno (errno);
|
||||||
|
log_error (_("error creating a pipe: %s\n"), strerror (errno));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_GNU_PTH
|
||||||
|
*pid = pth_fork? pth_fork () : fork ();
|
||||||
|
#else
|
||||||
|
*pid = fork ();
|
||||||
|
#endif
|
||||||
|
if (*pid == (pid_t)(-1))
|
||||||
|
{
|
||||||
|
err = gpg_error_from_errno (errno);
|
||||||
|
log_error (_("error forking process: %s\n"), strerror (errno));
|
||||||
|
close (rp[0]);
|
||||||
|
close (rp[1]);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*pid)
|
||||||
|
{
|
||||||
|
/* Child. */
|
||||||
|
char **arg_list;
|
||||||
|
int n, i, j;
|
||||||
|
|
||||||
|
/* Create the command line argument array. */
|
||||||
|
for (i=0; argv[i]; i++)
|
||||||
|
;
|
||||||
|
arg_list = xcalloc (i+2, sizeof *arg_list);
|
||||||
|
arg_list[0] = strrchr (pgmname, '/');
|
||||||
|
if (arg_list[0])
|
||||||
|
arg_list[0]++;
|
||||||
|
else
|
||||||
|
arg_list[0] = xstrdup (pgmname);
|
||||||
|
for (i=0,j=1; argv[i]; i++, j++)
|
||||||
|
arg_list[j] = (char*)argv[i];
|
||||||
|
|
||||||
|
/* Connect the infile to stdin. */
|
||||||
|
if (fd != 0 && dup2 (fd, 0) == -1)
|
||||||
|
log_fatal ("dup2 stdin failed: %s\n", strerror (errno));
|
||||||
|
|
||||||
|
/* Connect the outfile to stdout. */
|
||||||
|
if (fdout != 1 && dup2 (fdout, 1) == -1)
|
||||||
|
log_fatal ("dup2 stdout failed: %s\n", strerror (errno));
|
||||||
|
|
||||||
|
/* Connect stderr to our pipe. */
|
||||||
|
if (rp[1] != 2 && dup2 (rp[1], 2) == -1)
|
||||||
|
log_fatal ("dup2 stderr failed: %s\n", strerror (errno));
|
||||||
|
|
||||||
|
/* Close all other files. */
|
||||||
|
n = sysconf (_SC_OPEN_MAX);
|
||||||
|
if (n < 0)
|
||||||
|
n = MAX_OPEN_FDS;
|
||||||
|
for (i=3; i < n; i++)
|
||||||
|
close(i);
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
if (preexec)
|
||||||
|
preexec ();
|
||||||
|
execv (pgmname, arg_list);
|
||||||
|
/* No way to print anything, as we have closed all streams. */
|
||||||
|
_exit (127);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parent. */
|
||||||
|
close (rp[1]);
|
||||||
|
|
||||||
|
*statusfile = fdopen (rp[0], "r");
|
||||||
|
if (!*statusfile)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_errno (errno);
|
||||||
|
log_error (_("can't fdopen pipe for reading: %s\n"), strerror (errno));
|
||||||
|
kill (*pid, SIGTERM);
|
||||||
|
*pid = (pid_t)(-1);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif /* !_WIN32 */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Wait for the process identified by PID to terminate. PGMNAME should
|
||||||
|
be the same as suplieed to the spawn fucntion and is only used for
|
||||||
|
diagnostics. Returns 0 if the process succeded, GPG_ERR_GENERAL for
|
||||||
|
any failures of the spawned program or other error codes.*/
|
||||||
|
gpg_error_t
|
||||||
|
gnupg_wait_process (const char *pgmname, pid_t pid)
|
||||||
|
{
|
||||||
|
gpg_err_code_t ec;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
ec = GPG_ERR_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
|
#else /* !_WIN32 */
|
||||||
|
int i, status;
|
||||||
|
|
||||||
|
if (pid == (pid_t)(-1))
|
||||||
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
|
#ifdef USE_GNU_PTH
|
||||||
|
i = pth_waitpid ? pth_waitpid (pid, &status, 0) : waitpid (pid, &status, 0);
|
||||||
|
#else
|
||||||
|
while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
|
||||||
|
;
|
||||||
|
#endif
|
||||||
|
if (i == (pid_t)(-1))
|
||||||
|
{
|
||||||
|
log_error (_("waiting for process %d to terminate failed: %s\n"),
|
||||||
|
(int)pid, strerror (errno));
|
||||||
|
ec = gpg_err_code_from_errno (errno);
|
||||||
|
}
|
||||||
|
else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
|
||||||
|
{
|
||||||
|
log_error (_("error running `%s': probably not installed\n"), pgmname);
|
||||||
|
ec = GPG_ERR_CONFIGURATION;
|
||||||
|
}
|
||||||
|
else if (WIFEXITED (status) && WEXITSTATUS (status))
|
||||||
|
{
|
||||||
|
log_error (_("error running `%s': exit status %d\n"), pgmname,
|
||||||
|
WEXITSTATUS (status));
|
||||||
|
ec = GPG_ERR_GENERAL;
|
||||||
|
}
|
||||||
|
else if (!WIFEXITED (status))
|
||||||
|
{
|
||||||
|
log_error (_("error running `%s': terminated\n"), pgmname);
|
||||||
|
ec = GPG_ERR_GENERAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ec = 0;
|
||||||
|
#endif /* !_WIN32 */
|
||||||
|
|
||||||
|
return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
45
common/exechelp.h
Normal file
45
common/exechelp.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/* exechelp.h - Definitions for the fork and exec helpers
|
||||||
|
* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GNUPG_COMMON_EXECHELP_H
|
||||||
|
#define GNUPG_COMMON_EXECHELP_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
|
||||||
|
stdin, write the output to OUTFILE, return a new stream in
|
||||||
|
STATUSFILE for stderr and the pid of the process in PID. The
|
||||||
|
arguments for the process are expected in the NULL terminated array
|
||||||
|
ARGV. The program name itself should not be included there. if
|
||||||
|
PREEXEC is not NULL, that function will be called right before the
|
||||||
|
exec. Returns 0 on success or an error code. */
|
||||||
|
gpg_error_t gnupg_spawn_process (const char *pgmname, const char *argv[],
|
||||||
|
FILE *infile, FILE *outfile,
|
||||||
|
void (*preexec)(void),
|
||||||
|
FILE **statusfile, pid_t *pid);
|
||||||
|
|
||||||
|
/* Wait for the process identified by PID to terminate. PGMNAME should
|
||||||
|
be the same as suplieed to the spawn fucntion and is only used for
|
||||||
|
diagnostics. Returns 0 if the process succeded, GPG_ERR_GENERAL for
|
||||||
|
any failures of the spawned program or other error codes.*/
|
||||||
|
gpg_error_t gnupg_wait_process (const char *pgmname, pid_t pid);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*GNUPG_COMMON_EXECHELP_H*/
|
@ -1,5 +1,13 @@
|
|||||||
2004-12-06 Werner Koch <wk@g10code.com>
|
2004-12-06 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* gpgsm.c (run_protect_tool) [_WIN32]: Disabled.
|
||||||
|
|
||||||
|
* import.c (popen_protect_tool): Simplified by making use of
|
||||||
|
gnupg_spawn_process.
|
||||||
|
(parse_p12): Likewise, using gnupg_wait_process.
|
||||||
|
* export.c (popen_protect_tool): Ditto.
|
||||||
|
(export_p12): Ditto.
|
||||||
|
|
||||||
* keydb.c: Don't define DIRSEP_S here.
|
* keydb.c: Don't define DIRSEP_S here.
|
||||||
|
|
||||||
2004-12-02 Werner Koch <wk@g10code.com>
|
2004-12-02 Werner Koch <wk@g10code.com>
|
||||||
|
127
sm/export.c
127
sm/export.c
@ -23,25 +23,17 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
|
|
||||||
#include "gpgsm.h"
|
#include "gpgsm.h"
|
||||||
#include <gcrypt.h>
|
#include <gcrypt.h>
|
||||||
#include <ksba.h>
|
#include <ksba.h>
|
||||||
|
|
||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
|
#include "exechelp.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
#ifdef _POSIX_OPEN_MAX
|
|
||||||
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
|
|
||||||
#else
|
|
||||||
#define MAX_OPEN_FDS 20
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* A table to store a fingerprint as used in a duplicates table. We
|
/* A table to store a fingerprint as used in a duplicates table. We
|
||||||
@ -522,92 +514,23 @@ popen_protect_tool (const char *pgmname,
|
|||||||
const char *prompt, const char *keygrip,
|
const char *prompt, const char *keygrip,
|
||||||
pid_t *pid)
|
pid_t *pid)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
const char *argv[20];
|
||||||
int fd, fdout, rp[2];
|
int i=0;
|
||||||
int n, i;
|
|
||||||
|
|
||||||
fflush (infile);
|
argv[i++] = "--homedir";
|
||||||
rewind (infile);
|
argv[i++] = opt.homedir;
|
||||||
fd = fileno (infile);
|
argv[i++] = "--p12-export";
|
||||||
fdout = fileno (outfile);
|
argv[i++] = "--prompt";
|
||||||
if (fd == -1 || fdout == -1)
|
argv[i++] = prompt?prompt:"";
|
||||||
log_fatal ("no file descriptor for temporary file: %s\n",
|
argv[i++] = "--enable-status-msg";
|
||||||
strerror (errno));
|
argv[i++] = "--",
|
||||||
|
argv[i++] = keygrip,
|
||||||
|
argv[i] = NULL;
|
||||||
|
assert (i < sizeof argv);
|
||||||
|
|
||||||
/* Now start the protect-tool. */
|
return gnupg_spawn_process (pgmname, argv, infile, outfile,
|
||||||
if (pipe (rp) == -1)
|
setup_pinentry_env,
|
||||||
{
|
statusfile, pid);
|
||||||
err = gpg_error_from_errno (errno);
|
|
||||||
log_error (_("error creating a pipe: %s\n"), strerror (errno));
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pid = fork ();
|
|
||||||
if (*pid == -1)
|
|
||||||
{
|
|
||||||
err = gpg_error_from_errno (errno);
|
|
||||||
log_error (_("error forking process: %s\n"), strerror (errno));
|
|
||||||
close (rp[0]);
|
|
||||||
close (rp[1]);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!*pid)
|
|
||||||
{ /* Child. */
|
|
||||||
const char *arg0;
|
|
||||||
|
|
||||||
arg0 = strrchr (pgmname, '/');
|
|
||||||
if (arg0)
|
|
||||||
arg0++;
|
|
||||||
else
|
|
||||||
arg0 = pgmname;
|
|
||||||
|
|
||||||
/* Connect the infile to stdin. */
|
|
||||||
if (fd != 0 && dup2 (fd, 0) == -1)
|
|
||||||
log_fatal ("dup2 stdin failed: %s\n", strerror (errno));
|
|
||||||
|
|
||||||
/* Connect the outfile to stdout. */
|
|
||||||
if (fdout != 1 && dup2 (fdout, 1) == -1)
|
|
||||||
log_fatal ("dup2 stdout failed: %s\n", strerror (errno));
|
|
||||||
|
|
||||||
/* Connect stderr to our pipe. */
|
|
||||||
if (rp[1] != 2 && dup2 (rp[1], 2) == -1)
|
|
||||||
log_fatal ("dup2 stderr failed: %s\n", strerror (errno));
|
|
||||||
|
|
||||||
/* Close all other files. */
|
|
||||||
n = sysconf (_SC_OPEN_MAX);
|
|
||||||
if (n < 0)
|
|
||||||
n = MAX_OPEN_FDS;
|
|
||||||
for (i=3; i < n; i++)
|
|
||||||
close(i);
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
setup_pinentry_env ();
|
|
||||||
|
|
||||||
execlp (pgmname, arg0,
|
|
||||||
"--homedir", opt.homedir,
|
|
||||||
"--p12-export",
|
|
||||||
"--prompt", prompt?prompt:"",
|
|
||||||
"--enable-status-msg",
|
|
||||||
"--",
|
|
||||||
keygrip,
|
|
||||||
NULL);
|
|
||||||
/* No way to print anything, as we have closed all streams. */
|
|
||||||
_exit (31);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parent. */
|
|
||||||
close (rp[1]);
|
|
||||||
*statusfile = fdopen (rp[0], "r");
|
|
||||||
if (!*statusfile)
|
|
||||||
{
|
|
||||||
err = gpg_error_from_errno (errno);
|
|
||||||
log_error ("can't fdopen pipe for reading: %s", strerror (errno));
|
|
||||||
kill (*pid, SIGTERM);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -618,7 +541,7 @@ export_p12 (ctrl_t ctrl, const unsigned char *certimg, size_t certimglen,
|
|||||||
{
|
{
|
||||||
const char *pgmname;
|
const char *pgmname;
|
||||||
gpg_error_t err = 0, child_err = 0;
|
gpg_error_t err = 0, child_err = 0;
|
||||||
int i, c, cont_line;
|
int c, cont_line;
|
||||||
unsigned int pos;
|
unsigned int pos;
|
||||||
FILE *infp = NULL, *outfp = NULL, *fp = NULL;
|
FILE *infp = NULL, *outfp = NULL, *fp = NULL;
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
@ -722,21 +645,7 @@ export_p12 (ctrl_t ctrl, const unsigned char *certimg, size_t certimglen,
|
|||||||
fclose (fp);
|
fclose (fp);
|
||||||
if (pid != -1)
|
if (pid != -1)
|
||||||
{
|
{
|
||||||
int status;
|
if (!gnupg_wait_process (pgmname, pid))
|
||||||
|
|
||||||
while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
|
|
||||||
;
|
|
||||||
if (i == -1)
|
|
||||||
log_error (_("waiting for protect-tools to terminate failed: %s\n"),
|
|
||||||
strerror (errno));
|
|
||||||
else if (WIFEXITED (status) && WEXITSTATUS (status) == 31)
|
|
||||||
log_error (_("error running `%s': probably not installed\n"), pgmname);
|
|
||||||
else if (WIFEXITED (status) && WEXITSTATUS (status))
|
|
||||||
log_error (_("error running `%s': exit status %d\n"), pgmname,
|
|
||||||
WEXITSTATUS (status));
|
|
||||||
else if (!WIFEXITED (status))
|
|
||||||
log_error (_("error running `%s': terminated\n"), pgmname);
|
|
||||||
else
|
|
||||||
child_err = 0;
|
child_err = 0;
|
||||||
}
|
}
|
||||||
if (!err)
|
if (!err)
|
||||||
|
@ -1688,6 +1688,7 @@ open_fwrite (const char *filename)
|
|||||||
static void
|
static void
|
||||||
run_protect_tool (int argc, char **argv)
|
run_protect_tool (int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
#ifndef _WIN32
|
||||||
const char *pgm;
|
const char *pgm;
|
||||||
char **av;
|
char **av;
|
||||||
int i;
|
int i;
|
||||||
@ -1706,5 +1707,6 @@ run_protect_tool (int argc, char **argv)
|
|||||||
av[i] = NULL;
|
av[i] = NULL;
|
||||||
execv (pgm, av);
|
execv (pgm, av);
|
||||||
log_error ("error executing `%s': %s\n", pgm, strerror (errno));
|
log_error ("error executing `%s': %s\n", pgm, strerror (errno));
|
||||||
|
#endif
|
||||||
gpgsm_exit (2);
|
gpgsm_exit (2);
|
||||||
}
|
}
|
||||||
|
141
sm/import.c
141
sm/import.c
@ -23,27 +23,17 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
|
|
||||||
#include "gpgsm.h"
|
#include "gpgsm.h"
|
||||||
#include <gcrypt.h>
|
#include <gcrypt.h>
|
||||||
#include <ksba.h>
|
#include <ksba.h>
|
||||||
|
|
||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
|
#include "exechelp.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
#ifdef _POSIX_OPEN_MAX
|
|
||||||
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
|
|
||||||
#else
|
|
||||||
#define MAX_OPEN_FDS 20
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
struct stats_s {
|
struct stats_s {
|
||||||
unsigned long count;
|
unsigned long count;
|
||||||
unsigned long imported;
|
unsigned long imported;
|
||||||
@ -471,103 +461,27 @@ static gpg_error_t
|
|||||||
popen_protect_tool (const char *pgmname,
|
popen_protect_tool (const char *pgmname,
|
||||||
FILE *infile, FILE *outfile, FILE **statusfile, pid_t *pid)
|
FILE *infile, FILE *outfile, FILE **statusfile, pid_t *pid)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
const char *argv[20];
|
||||||
int fd, fdout, rp[2];
|
int i=0;
|
||||||
int n, i;
|
|
||||||
|
|
||||||
fflush (infile);
|
argv[i++] = "--homedir";
|
||||||
rewind (infile);
|
argv[i++] = opt.homedir;
|
||||||
fd = fileno (infile);
|
argv[i++] = "--p12-import";
|
||||||
fdout = fileno (outfile);
|
argv[i++] = "--store";
|
||||||
if (fd == -1 || fdout == -1)
|
argv[i++] = "--no-fail-on-exist";
|
||||||
log_fatal ("no file descriptor for temporary file: %s\n",
|
argv[i++] = "--enable-status-msg";
|
||||||
strerror (errno));
|
if (opt.fixed_passphrase)
|
||||||
|
|
||||||
/* Now start the protect-tool. */
|
|
||||||
if (pipe (rp) == -1)
|
|
||||||
{
|
{
|
||||||
err = gpg_error_from_errno (errno);
|
argv[i++] = "--passphrase";
|
||||||
log_error (_("error creating a pipe: %s\n"), strerror (errno));
|
argv[i++] = opt.fixed_passphrase;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pid = fork ();
|
|
||||||
if (*pid == -1)
|
|
||||||
{
|
|
||||||
err = gpg_error_from_errno (errno);
|
|
||||||
log_error (_("error forking process: %s\n"), strerror (errno));
|
|
||||||
close (rp[0]);
|
|
||||||
close (rp[1]);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
argv[i++] = "--",
|
||||||
|
argv[i] = NULL;
|
||||||
|
assert (i < sizeof argv);
|
||||||
|
|
||||||
if (!*pid)
|
return gnupg_spawn_process (pgmname, argv, infile, outfile,
|
||||||
{ /* Child. */
|
setup_pinentry_env,
|
||||||
const char *arg0;
|
statusfile, pid);
|
||||||
|
|
||||||
arg0 = strrchr (pgmname, '/');
|
|
||||||
if (arg0)
|
|
||||||
arg0++;
|
|
||||||
else
|
|
||||||
arg0 = pgmname;
|
|
||||||
|
|
||||||
/* Connect the infile to stdin. */
|
|
||||||
if (fd != 0 && dup2 (fd, 0) == -1)
|
|
||||||
log_fatal ("dup2 stdin failed: %s\n", strerror (errno));
|
|
||||||
|
|
||||||
/* Connect the outfile to stdout. */
|
|
||||||
if (fdout != 1 && dup2 (fdout, 1) == -1)
|
|
||||||
log_fatal ("dup2 stdout failed: %s\n", strerror (errno));
|
|
||||||
|
|
||||||
/* Connect stderr to our pipe. */
|
|
||||||
if (rp[1] != 2 && dup2 (rp[1], 2) == -1)
|
|
||||||
log_fatal ("dup2 stderr failed: %s\n", strerror (errno));
|
|
||||||
|
|
||||||
/* Close all other files. */
|
|
||||||
n = sysconf (_SC_OPEN_MAX);
|
|
||||||
if (n < 0)
|
|
||||||
n = MAX_OPEN_FDS;
|
|
||||||
for (i=3; i < n; i++)
|
|
||||||
close(i);
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
setup_pinentry_env ();
|
|
||||||
|
|
||||||
if (opt.fixed_passphrase)
|
|
||||||
execlp (pgmname, arg0,
|
|
||||||
"--homedir", opt.homedir,
|
|
||||||
"--p12-import",
|
|
||||||
"--store",
|
|
||||||
"--no-fail-on-exist",
|
|
||||||
"--enable-status-msg",
|
|
||||||
"--passphrase", opt.fixed_passphrase,
|
|
||||||
"--",
|
|
||||||
NULL);
|
|
||||||
else
|
|
||||||
execlp (pgmname, arg0,
|
|
||||||
"--homedir", opt.homedir,
|
|
||||||
"--p12-import",
|
|
||||||
"--store",
|
|
||||||
"--no-fail-on-exist",
|
|
||||||
"--enable-status-msg",
|
|
||||||
"--",
|
|
||||||
NULL);
|
|
||||||
/* No way to print anything, as we have closed all streams. */
|
|
||||||
_exit (31);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parent. */
|
|
||||||
close (rp[1]);
|
|
||||||
*statusfile = fdopen (rp[0], "r");
|
|
||||||
if (!*statusfile)
|
|
||||||
{
|
|
||||||
err = gpg_error_from_errno (errno);
|
|
||||||
log_error ("can't fdopen pipe for reading: %s", strerror (errno));
|
|
||||||
kill (*pid, SIGTERM);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -583,7 +497,7 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader,
|
|||||||
{
|
{
|
||||||
const char *pgmname;
|
const char *pgmname;
|
||||||
gpg_error_t err = 0, child_err = 0;
|
gpg_error_t err = 0, child_err = 0;
|
||||||
int i, c, cont_line;
|
int c, cont_line;
|
||||||
unsigned int pos;
|
unsigned int pos;
|
||||||
FILE *tmpfp, *certfp = NULL, *fp = NULL;
|
FILE *tmpfp, *certfp = NULL, *fp = NULL;
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
@ -712,7 +626,6 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader,
|
|||||||
if (!child_err)
|
if (!child_err)
|
||||||
child_err = gpg_error (GPG_ERR_DECRYPT_FAILED);
|
child_err = gpg_error (GPG_ERR_DECRYPT_FAILED);
|
||||||
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (tmpfp)
|
if (tmpfp)
|
||||||
fclose (tmpfp);
|
fclose (tmpfp);
|
||||||
@ -720,21 +633,7 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader,
|
|||||||
fclose (fp);
|
fclose (fp);
|
||||||
if (pid != -1)
|
if (pid != -1)
|
||||||
{
|
{
|
||||||
int status;
|
if (!gnupg_wait_process (pgmname, pid))
|
||||||
|
|
||||||
while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
|
|
||||||
;
|
|
||||||
if (i == -1)
|
|
||||||
log_error (_("waiting for protect-tool to terminate failed: %s\n"),
|
|
||||||
strerror (errno));
|
|
||||||
else if (WIFEXITED (status) && WEXITSTATUS (status) == 31)
|
|
||||||
log_error (_("error running `%s': probably not installed\n"), pgmname);
|
|
||||||
else if (WIFEXITED (status) && WEXITSTATUS (status))
|
|
||||||
log_error (_("error running `%s': exit status %d\n"), pgmname,
|
|
||||||
WEXITSTATUS (status));
|
|
||||||
else if (!WIFEXITED (status))
|
|
||||||
log_error (_("error running `%s': terminated\n"), pgmname);
|
|
||||||
else
|
|
||||||
child_err = 0;
|
child_err = 0;
|
||||||
}
|
}
|
||||||
if (!err)
|
if (!err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user