mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-31 11:41:32 +01:00
kbx: Add framework for a public key daemon.
* kbx/keyboxd.c: New. * kbx/keyboxd.h: New. * kbx/kbxserver.c: New. * kbx/keyboxd-w32info.rc: New. * kbx/Makefile.am (EXTRA_DIST): Add new rc file. (resource_objs): Ditto. (libexec_PROGRAMS): New. (common_libs, commonpth_libs): New. (kbxutil_LDADD): Use here. (keyboxd_SOURCES): New. (keyboxd_CFLAGS): New. (keyboxd_LDADD): New. (keyboxd_LDFLAGS): New. (keyboxd_DEPENDENCIES): new. ($(PROGRAMS)): Extend. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
d4489be467
commit
512be1d04b
@ -56,7 +56,7 @@ AC_DEFINE_UNQUOTED(GNUPG_SWDB_TAG, "gnupg24", [swdb tag for this branch])
|
|||||||
NEED_GPG_ERROR_VERSION=1.29
|
NEED_GPG_ERROR_VERSION=1.29
|
||||||
|
|
||||||
NEED_LIBGCRYPT_API=1
|
NEED_LIBGCRYPT_API=1
|
||||||
NEED_LIBGCRYPT_VERSION=1.7.0
|
NEED_LIBGCRYPT_VERSION=1.8.0
|
||||||
|
|
||||||
NEED_LIBASSUAN_API=2
|
NEED_LIBASSUAN_API=2
|
||||||
NEED_LIBASSUAN_VERSION=2.5.0
|
NEED_LIBASSUAN_VERSION=2.5.0
|
||||||
@ -505,6 +505,7 @@ AH_BOTTOM([
|
|||||||
#define GNUPG_DEFAULT_HOMEDIR "~/.gnupg"
|
#define GNUPG_DEFAULT_HOMEDIR "~/.gnupg"
|
||||||
#endif
|
#endif
|
||||||
#define GNUPG_PRIVATE_KEYS_DIR "private-keys-v1.d"
|
#define GNUPG_PRIVATE_KEYS_DIR "private-keys-v1.d"
|
||||||
|
#define GNUPG_PUBLIC_KEYS_DIR "public-keys.d"
|
||||||
#define GNUPG_OPENPGP_REVOC_DIR "openpgp-revocs.d"
|
#define GNUPG_OPENPGP_REVOC_DIR "openpgp-revocs.d"
|
||||||
|
|
||||||
#define GNUPG_DEF_COPYRIGHT_LINE \
|
#define GNUPG_DEF_COPYRIGHT_LINE \
|
||||||
@ -1882,6 +1883,8 @@ AC_DEFINE_UNQUOTED(DIRMNGR_INFO_NAME, "DIRMNGR_INFO",
|
|||||||
[The name of the dirmngr info envvar])
|
[The name of the dirmngr info envvar])
|
||||||
AC_DEFINE_UNQUOTED(SCDAEMON_SOCK_NAME, "S.scdaemon",
|
AC_DEFINE_UNQUOTED(SCDAEMON_SOCK_NAME, "S.scdaemon",
|
||||||
[The name of the SCdaemon socket])
|
[The name of the SCdaemon socket])
|
||||||
|
AC_DEFINE_UNQUOTED(KEYBOXD_SOCK_NAME, "S.keyboxd",
|
||||||
|
[The name of the keyboxd socket])
|
||||||
AC_DEFINE_UNQUOTED(DIRMNGR_SOCK_NAME, "S.dirmngr",
|
AC_DEFINE_UNQUOTED(DIRMNGR_SOCK_NAME, "S.dirmngr",
|
||||||
[The name of the dirmngr socket])
|
[The name of the dirmngr socket])
|
||||||
AC_DEFINE_UNQUOTED(DIRMNGR_DEFAULT_KEYSERVER,
|
AC_DEFINE_UNQUOTED(DIRMNGR_DEFAULT_KEYSERVER,
|
||||||
|
@ -18,16 +18,20 @@
|
|||||||
|
|
||||||
## Process this file with automake to produce Makefile.in
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
EXTRA_DIST = mkerrors
|
EXTRA_DIST = mkerrors keyboxd-w32info.rc
|
||||||
|
|
||||||
AM_CPPFLAGS =
|
AM_CPPFLAGS =
|
||||||
|
|
||||||
include $(top_srcdir)/am/cmacros.am
|
include $(top_srcdir)/am/cmacros.am
|
||||||
|
if HAVE_W32_SYSTEM
|
||||||
|
resource_objs += keyboxd-w32info.o
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS)
|
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS)
|
||||||
|
|
||||||
noinst_LIBRARIES = libkeybox.a libkeybox509.a
|
noinst_LIBRARIES = libkeybox.a libkeybox509.a
|
||||||
bin_PROGRAMS = kbxutil
|
bin_PROGRAMS = kbxutil
|
||||||
|
libexec_PROGRAMS = keyboxd
|
||||||
|
|
||||||
if HAVE_W32CE_SYSTEM
|
if HAVE_W32CE_SYSTEM
|
||||||
extra_libs = $(LIBASSUAN_LIBS)
|
extra_libs = $(LIBASSUAN_LIBS)
|
||||||
@ -35,6 +39,9 @@ else
|
|||||||
extra_libs =
|
extra_libs =
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
common_libs = $(libcommon)
|
||||||
|
commonpth_libs = $(libcommonpth)
|
||||||
|
|
||||||
common_sources = \
|
common_sources = \
|
||||||
keybox.h keybox-defs.h keybox-search-desc.h \
|
keybox.h keybox-defs.h keybox-search-desc.h \
|
||||||
keybox-util.c \
|
keybox-util.c \
|
||||||
@ -59,9 +66,26 @@ libkeybox509_a_CFLAGS = $(AM_CFLAGS) -DKEYBOX_WITH_X509=1
|
|||||||
# to do it this way.
|
# to do it this way.
|
||||||
kbxutil_SOURCES = kbxutil.c $(common_sources)
|
kbxutil_SOURCES = kbxutil.c $(common_sources)
|
||||||
kbxutil_CFLAGS = $(AM_CFLAGS) -DKEYBOX_WITH_X509=1
|
kbxutil_CFLAGS = $(AM_CFLAGS) -DKEYBOX_WITH_X509=1
|
||||||
kbxutil_LDADD = ../common/libcommon.a \
|
kbxutil_LDADD = $(common_libs) \
|
||||||
$(KSBA_LIBS) $(LIBGCRYPT_LIBS) $(extra_libs) \
|
$(KSBA_LIBS) $(LIBGCRYPT_LIBS) $(extra_libs) \
|
||||||
$(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) $(W32SOCKLIBS) \
|
$(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) $(W32SOCKLIBS) \
|
||||||
$(NETLIBS)
|
$(NETLIBS)
|
||||||
|
|
||||||
$(PROGRAMS) : ../common/libcommon.a
|
|
||||||
|
keyboxd_SOURCES = \
|
||||||
|
keyboxd.c keyboxd.h \
|
||||||
|
kbxserver.c
|
||||||
|
|
||||||
|
keyboxd_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS) \
|
||||||
|
$(INCICONV)
|
||||||
|
keyboxd_LDADD = $(commonpth_libs) \
|
||||||
|
$(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \
|
||||||
|
$(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) \
|
||||||
|
$(resource_objs)
|
||||||
|
keyboxd_LDFLAGS = $(extra_bin_ldflags)
|
||||||
|
keyboxd_DEPENDENCIES = $(resource_objs)
|
||||||
|
|
||||||
|
|
||||||
|
# Make sure that all libs are build before we use them. This is
|
||||||
|
# important for things like make -j2.
|
||||||
|
$(PROGRAMS): $(common_libs) $(commonpth_libs)
|
||||||
|
447
kbx/kbxserver.c
Normal file
447
kbx/kbxserver.c
Normal file
@ -0,0 +1,447 @@
|
|||||||
|
/* kbxserver.c - Handle Assuan commands send to the keyboxd
|
||||||
|
* Copyright (C) 2018 g10 Code GmbH
|
||||||
|
*
|
||||||
|
* 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||||
|
* SPDX-License-Identifier: GPL-3.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "keyboxd.h"
|
||||||
|
#include <assuan.h>
|
||||||
|
|
||||||
|
#include "../common/i18n.h"
|
||||||
|
#include "../common/server-help.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define PARM_ERROR(t) assuan_set_error (ctx, \
|
||||||
|
gpg_error (GPG_ERR_ASS_PARAMETER), (t))
|
||||||
|
#define set_error(e,t) (ctx ? assuan_set_error (ctx, gpg_error (e), (t)) \
|
||||||
|
/**/: gpg_error (e))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Control structure per connection. */
|
||||||
|
struct server_local_s
|
||||||
|
{
|
||||||
|
/* Data used to associate an Assuan context with local server data */
|
||||||
|
assuan_context_t assuan_ctx;
|
||||||
|
|
||||||
|
/* The session id (a counter). */
|
||||||
|
unsigned int session_id;
|
||||||
|
|
||||||
|
/* If this flag is set to true this process will be terminated after
|
||||||
|
* the end of this session. */
|
||||||
|
int stopme;
|
||||||
|
|
||||||
|
/* If the first both flags are set the assuan logging of data lines
|
||||||
|
* is suppressed. The count variable is used to show the number of
|
||||||
|
* non-logged bytes. */
|
||||||
|
size_t inhibit_data_logging_count;
|
||||||
|
unsigned int inhibit_data_logging : 1;
|
||||||
|
unsigned int inhibit_data_logging_now : 1;
|
||||||
|
|
||||||
|
/* Dummy option. */
|
||||||
|
int foo;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper to print a message while leaving a command. */
|
||||||
|
static gpg_error_t
|
||||||
|
leave_cmd (assuan_context_t ctx, gpg_error_t err)
|
||||||
|
{
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
const char *name = assuan_get_command_name (ctx);
|
||||||
|
if (!name)
|
||||||
|
name = "?";
|
||||||
|
if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
|
||||||
|
log_error ("command '%s' failed: %s\n", name,
|
||||||
|
gpg_strerror (err));
|
||||||
|
else
|
||||||
|
log_error ("command '%s' failed: %s <%s>\n", name,
|
||||||
|
gpg_strerror (err), gpg_strsource (err));
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Handle OPTION commands. */
|
||||||
|
static gpg_error_t
|
||||||
|
option_handler (assuan_context_t ctx, const char *key, const char *value)
|
||||||
|
{
|
||||||
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
|
gpg_error_t err = 0;
|
||||||
|
|
||||||
|
if (!strcmp (key, "foo"))
|
||||||
|
{
|
||||||
|
ctrl->server_local->foo = 1;
|
||||||
|
}
|
||||||
|
else if (!strcmp (key, "lc-messages"))
|
||||||
|
{
|
||||||
|
if (ctrl->lc_messages)
|
||||||
|
xfree (ctrl->lc_messages);
|
||||||
|
ctrl->lc_messages = xtrystrdup (value);
|
||||||
|
if (!ctrl->lc_messages)
|
||||||
|
return out_of_core ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const char hlp_foo[] =
|
||||||
|
"FOO <user_id>\n"
|
||||||
|
"\n"
|
||||||
|
"Bla bla\n"
|
||||||
|
"more bla.";
|
||||||
|
static gpg_error_t
|
||||||
|
cmd_foo (assuan_context_t ctx, char *line)
|
||||||
|
{
|
||||||
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
|
gpg_error_t err;
|
||||||
|
|
||||||
|
(void)ctrl;
|
||||||
|
(void)line;
|
||||||
|
|
||||||
|
err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
|
|
||||||
|
return leave_cmd (ctx, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const char hlp_getinfo[] =
|
||||||
|
"GETINFO <what>\n"
|
||||||
|
"\n"
|
||||||
|
"Multi purpose command to return certain information. \n"
|
||||||
|
"Supported values of WHAT are:\n"
|
||||||
|
"\n"
|
||||||
|
"version - Return the version of the program.\n"
|
||||||
|
"pid - Return the process id of the server.\n"
|
||||||
|
"socket_name - Return the name of the socket.\n"
|
||||||
|
"session_id - Return the current session_id.\n"
|
||||||
|
"getenv NAME - Return value of envvar NAME\n";
|
||||||
|
static gpg_error_t
|
||||||
|
cmd_getinfo (assuan_context_t ctx, char *line)
|
||||||
|
{
|
||||||
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
|
gpg_error_t err;
|
||||||
|
char numbuf[50];
|
||||||
|
|
||||||
|
if (!strcmp (line, "version"))
|
||||||
|
{
|
||||||
|
const char *s = VERSION;
|
||||||
|
err = assuan_send_data (ctx, s, strlen (s));
|
||||||
|
}
|
||||||
|
else if (!strcmp (line, "pid"))
|
||||||
|
{
|
||||||
|
snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
|
||||||
|
err = assuan_send_data (ctx, numbuf, strlen (numbuf));
|
||||||
|
}
|
||||||
|
else if (!strcmp (line, "socket_name"))
|
||||||
|
{
|
||||||
|
const char *s = get_kbxd_socket_name ();
|
||||||
|
if (!s)
|
||||||
|
s = "[none]";
|
||||||
|
err = assuan_send_data (ctx, s, strlen (s));
|
||||||
|
}
|
||||||
|
else if (!strcmp (line, "session_id"))
|
||||||
|
{
|
||||||
|
snprintf (numbuf, sizeof numbuf, "%u", ctrl->server_local->session_id);
|
||||||
|
err = assuan_send_data (ctx, numbuf, strlen (numbuf));
|
||||||
|
}
|
||||||
|
else if (!strncmp (line, "getenv", 6)
|
||||||
|
&& (line[6] == ' ' || line[6] == '\t' || !line[6]))
|
||||||
|
{
|
||||||
|
line += 6;
|
||||||
|
while (*line == ' ' || *line == '\t')
|
||||||
|
line++;
|
||||||
|
if (!*line)
|
||||||
|
err = gpg_error (GPG_ERR_MISSING_VALUE);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char *s = getenv (line);
|
||||||
|
if (!s)
|
||||||
|
err = set_error (GPG_ERR_NOT_FOUND, "No such envvar");
|
||||||
|
else
|
||||||
|
err = assuan_send_data (ctx, s, strlen (s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
|
||||||
|
|
||||||
|
return leave_cmd (ctx, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const char hlp_killkeyboxd[] =
|
||||||
|
"KILLKEYBOXD\n"
|
||||||
|
"\n"
|
||||||
|
"This command allows a user - given sufficient permissions -\n"
|
||||||
|
"to kill this keyboxd process.\n";
|
||||||
|
static gpg_error_t
|
||||||
|
cmd_killkeyboxd (assuan_context_t ctx, char *line)
|
||||||
|
{
|
||||||
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
|
|
||||||
|
(void)line;
|
||||||
|
|
||||||
|
ctrl->server_local->stopme = 1;
|
||||||
|
assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
|
||||||
|
return gpg_error (GPG_ERR_EOF);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char hlp_reloadkeyboxd[] =
|
||||||
|
"RELOADKEYBOXD\n"
|
||||||
|
"\n"
|
||||||
|
"This command is an alternative to SIGHUP\n"
|
||||||
|
"to reload the configuration.";
|
||||||
|
static gpg_error_t
|
||||||
|
cmd_reloadkeyboxd (assuan_context_t ctx, char *line)
|
||||||
|
{
|
||||||
|
(void)ctx;
|
||||||
|
(void)line;
|
||||||
|
|
||||||
|
kbxd_sighup_action ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Tell the assuan library about our commands. */
|
||||||
|
static int
|
||||||
|
register_commands (assuan_context_t ctx)
|
||||||
|
{
|
||||||
|
static struct {
|
||||||
|
const char *name;
|
||||||
|
assuan_handler_t handler;
|
||||||
|
const char * const help;
|
||||||
|
} table[] = {
|
||||||
|
{ "FOO", cmd_foo, hlp_foo },
|
||||||
|
{ "GETINFO", cmd_getinfo, hlp_getinfo },
|
||||||
|
{ "KILLKEYBOXD",cmd_killkeyboxd,hlp_killkeyboxd },
|
||||||
|
{ "RELOADKEYBOXD",cmd_reloadkeyboxd,hlp_reloadkeyboxd },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
int i, j, rc;
|
||||||
|
|
||||||
|
for (i=j=0; table[i].name; i++)
|
||||||
|
{
|
||||||
|
rc = assuan_register_command (ctx, table[i].name, table[i].handler,
|
||||||
|
table[i].help);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Note that we do not reset the list of configured keyservers. */
|
||||||
|
static gpg_error_t
|
||||||
|
reset_notify (assuan_context_t ctx, char *line)
|
||||||
|
{
|
||||||
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
|
|
||||||
|
(void)line;
|
||||||
|
(void)ctrl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This function is called by our assuan log handler to test whether a
|
||||||
|
* log message shall really be printed. The function must return
|
||||||
|
* false to inhibit the logging of MSG. CAT gives the requested log
|
||||||
|
* category. MSG might be NULL. */
|
||||||
|
int
|
||||||
|
kbxd_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
|
||||||
|
const char *msg)
|
||||||
|
{
|
||||||
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
|
|
||||||
|
(void)cat;
|
||||||
|
(void)msg;
|
||||||
|
|
||||||
|
if (!ctrl || !ctrl->server_local)
|
||||||
|
return 1; /* Can't decide - allow logging. */
|
||||||
|
|
||||||
|
if (!ctrl->server_local->inhibit_data_logging)
|
||||||
|
return 1; /* Not requested - allow logging. */
|
||||||
|
|
||||||
|
/* Disallow logging if *_now is true. */
|
||||||
|
return !ctrl->server_local->inhibit_data_logging_now;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return the assuan contxt from the local server info in CTRL. */
|
||||||
|
static assuan_context_t
|
||||||
|
get_assuan_ctx_from_ctrl (ctrl_t ctrl)
|
||||||
|
{
|
||||||
|
if (!ctrl || !ctrl->server_local)
|
||||||
|
return NULL;
|
||||||
|
return ctrl->server_local->assuan_ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Startup the server and run the main command loop. With FD = -1,
|
||||||
|
* use stdin/stdout. SESSION_ID is either 0 or a unique number
|
||||||
|
* identifying a session. */
|
||||||
|
void
|
||||||
|
kbxd_start_command_handler (ctrl_t ctrl, gnupg_fd_t fd, unsigned int session_id)
|
||||||
|
{
|
||||||
|
static const char hello[] = "Keyboxd " VERSION " at your service";
|
||||||
|
static char *hello_line;
|
||||||
|
int rc;
|
||||||
|
assuan_context_t ctx;
|
||||||
|
|
||||||
|
ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
|
||||||
|
if (!ctrl->server_local)
|
||||||
|
{
|
||||||
|
log_error (_("can't allocate control structure: %s\n"),
|
||||||
|
gpg_strerror (gpg_error_from_syserror ()));
|
||||||
|
xfree (ctrl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = assuan_new (&ctx);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error (_("failed to allocate assuan context: %s\n"),
|
||||||
|
gpg_strerror (rc));
|
||||||
|
kbxd_exit (2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd == GNUPG_INVALID_FD)
|
||||||
|
{
|
||||||
|
assuan_fd_t filedes[2];
|
||||||
|
|
||||||
|
filedes[0] = assuan_fdopen (0);
|
||||||
|
filedes[1] = assuan_fdopen (1);
|
||||||
|
rc = assuan_init_pipe_server (ctx, filedes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
assuan_release (ctx);
|
||||||
|
log_error (_("failed to initialize the server: %s\n"),
|
||||||
|
gpg_strerror (rc));
|
||||||
|
kbxd_exit (2);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = register_commands (ctx);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error (_("failed to the register commands with Assuan: %s\n"),
|
||||||
|
gpg_strerror(rc));
|
||||||
|
kbxd_exit (2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!hello_line)
|
||||||
|
{
|
||||||
|
hello_line = xtryasprintf
|
||||||
|
("Home: %s\n"
|
||||||
|
"Config: %s\n"
|
||||||
|
"%s",
|
||||||
|
gnupg_homedir (),
|
||||||
|
/*opt.config_filename? opt.config_filename :*/ "[none]",
|
||||||
|
hello);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrl->server_local->assuan_ctx = ctx;
|
||||||
|
assuan_set_pointer (ctx, ctrl);
|
||||||
|
|
||||||
|
assuan_set_hello_line (ctx, hello_line);
|
||||||
|
assuan_register_option_handler (ctx, option_handler);
|
||||||
|
assuan_register_reset_notify (ctx, reset_notify);
|
||||||
|
|
||||||
|
ctrl->server_local->session_id = session_id;
|
||||||
|
|
||||||
|
/* The next call enable the use of status_printf. */
|
||||||
|
set_assuan_context_func (get_assuan_ctx_from_ctrl);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
rc = assuan_accept (ctx);
|
||||||
|
if (rc == -1)
|
||||||
|
break;
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_W32_SYSTEM
|
||||||
|
if (opt.verbose)
|
||||||
|
{
|
||||||
|
assuan_peercred_t peercred;
|
||||||
|
|
||||||
|
if (!assuan_get_peercred (ctx, &peercred))
|
||||||
|
log_info ("connection from process %ld (%ld:%ld)\n",
|
||||||
|
(long)peercred->pid, (long)peercred->uid,
|
||||||
|
(long)peercred->gid);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rc = assuan_process (ctx);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
set_assuan_context_func (NULL);
|
||||||
|
ctrl->server_local->assuan_ctx = NULL;
|
||||||
|
assuan_release (ctx);
|
||||||
|
|
||||||
|
if (ctrl->server_local->stopme)
|
||||||
|
kbxd_exit (0);
|
||||||
|
|
||||||
|
if (ctrl->refcount)
|
||||||
|
log_error ("oops: connection control structure still referenced (%d)\n",
|
||||||
|
ctrl->refcount);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xfree (ctrl->server_local);
|
||||||
|
ctrl->server_local = NULL;
|
||||||
|
}
|
||||||
|
}
|
50
kbx/keyboxd-w32info.rc
Normal file
50
kbx/keyboxd-w32info.rc
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* keyboxd-w32info.rc -*- c -*-
|
||||||
|
* Copyright (C) 2018 g10 Code GmbH
|
||||||
|
*
|
||||||
|
* This file is free software; as a special exception the author gives
|
||||||
|
* unlimited permission to copy and/or distribute it, with or without
|
||||||
|
* modifications, as long as this notice is preserved.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||||
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "afxres.h"
|
||||||
|
#include "../common/w32info-rc.h"
|
||||||
|
|
||||||
|
1 ICON "../common/gnupg.ico"
|
||||||
|
|
||||||
|
1 VERSIONINFO
|
||||||
|
FILEVERSION W32INFO_VI_FILEVERSION
|
||||||
|
PRODUCTVERSION W32INFO_VI_PRODUCTVERSION
|
||||||
|
FILEFLAGSMASK 0x3fL
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS 0x01L /* VS_FF_DEBUG (0x1)*/
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0x00L
|
||||||
|
#endif
|
||||||
|
FILEOS 0x40004L /* VOS_NT (0x40000) | VOS__WINDOWS32 (0x4) */
|
||||||
|
FILETYPE 0x1L /* VFT_APP (0x1) */
|
||||||
|
FILESUBTYPE 0x0L /* VFT2_UNKNOWN */
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904b0" /* US English (0409), Unicode (04b0) */
|
||||||
|
BEGIN
|
||||||
|
VALUE "FileDescription", L"GnuPG\x2019s public key daemon\0"
|
||||||
|
VALUE "InternalName", "keyboxd\0"
|
||||||
|
VALUE "OriginalFilename", "keyboxd.exe\0"
|
||||||
|
VALUE "ProductName", W32INFO_PRODUCTNAME
|
||||||
|
VALUE "ProductVersion", W32INFO_PRODUCTVERSION
|
||||||
|
VALUE "CompanyName", W32INFO_COMPANYNAME
|
||||||
|
VALUE "FileVersion", W32INFO_FILEVERSION
|
||||||
|
VALUE "LegalCopyright", W32INFO_LEGALCOPYRIGHT
|
||||||
|
VALUE "Comments", W32INFO_COMMENTS
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x409, 0x4b0
|
||||||
|
END
|
||||||
|
END
|
1817
kbx/keyboxd.c
Normal file
1817
kbx/keyboxd.c
Normal file
File diff suppressed because it is too large
Load Diff
137
kbx/keyboxd.h
Normal file
137
kbx/keyboxd.h
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/* keyboxd.h - Global definitions for keyboxd
|
||||||
|
* Copyright (C) 2018 Werner Koch
|
||||||
|
*
|
||||||
|
* 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KEYBOXD_H
|
||||||
|
#define KEYBOXD_H
|
||||||
|
|
||||||
|
#ifdef GPG_ERR_SOURCE_DEFAULT
|
||||||
|
#error GPG_ERR_SOURCE_DEFAULT already defined
|
||||||
|
#endif
|
||||||
|
#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_KEYBOX
|
||||||
|
#include <gpg-error.h>
|
||||||
|
|
||||||
|
#include <gcrypt.h>
|
||||||
|
#include "../common/util.h"
|
||||||
|
#include "../common/membuf.h"
|
||||||
|
#include "../common/sysutils.h" /* (gnupg_fd_t) */
|
||||||
|
|
||||||
|
|
||||||
|
/* A large struct name "opt" to keep global flags */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned int debug; /* Debug flags (DBG_foo_VALUE) */
|
||||||
|
int verbose; /* Verbosity level */
|
||||||
|
int quiet; /* Be as quiet as possible */
|
||||||
|
int dry_run; /* Don't change any persistent data */
|
||||||
|
int batch; /* Batch mode */
|
||||||
|
|
||||||
|
/* True if we are running detached from the tty. */
|
||||||
|
int running_detached;
|
||||||
|
|
||||||
|
} opt;
|
||||||
|
|
||||||
|
|
||||||
|
/* Bit values for the --debug option. */
|
||||||
|
#define DBG_MPI_VALUE 2 /* debug mpi details */
|
||||||
|
#define DBG_CRYPTO_VALUE 4 /* debug low level crypto */
|
||||||
|
#define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */
|
||||||
|
#define DBG_CACHE_VALUE 64 /* debug the caching */
|
||||||
|
#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */
|
||||||
|
#define DBG_HASHING_VALUE 512 /* debug hashing operations */
|
||||||
|
#define DBG_IPC_VALUE 1024 /* Enable Assuan debugging. */
|
||||||
|
|
||||||
|
/* Test macros for the debug option. */
|
||||||
|
#define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE)
|
||||||
|
#define DBG_MEMORY (opt.debug & DBG_MEMORY_VALUE)
|
||||||
|
#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE)
|
||||||
|
#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
|
||||||
|
#define DBG_IPC (opt.debug & DBG_IPC_VALUE)
|
||||||
|
|
||||||
|
/* Forward reference for local definitions in command.c. */
|
||||||
|
struct server_local_s;
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_LONG == 8
|
||||||
|
# define SERVER_CONTROL_MAGIC 0x6b6579626f786420
|
||||||
|
#else
|
||||||
|
# define SERVER_CONTROL_MAGIC 0x6b627864
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Collection of data per session (aka connection). */
|
||||||
|
struct server_control_s
|
||||||
|
{
|
||||||
|
unsigned long magic;/* Always has SERVER_CONTROL_MAGIC. */
|
||||||
|
int refcount; /* Count additional references to this object. */
|
||||||
|
|
||||||
|
/* Private data used to fire up the connection thread. We use this
|
||||||
|
* structure do avoid an extra allocation for only a few bytes while
|
||||||
|
* spawning a new connection thread. */
|
||||||
|
struct {
|
||||||
|
gnupg_fd_t fd;
|
||||||
|
} thread_startup;
|
||||||
|
|
||||||
|
/* Private data of the server (kbxserver.c). */
|
||||||
|
struct server_local_s *server_local;
|
||||||
|
|
||||||
|
/* Environment settings for the connection. */
|
||||||
|
char *lc_messages;
|
||||||
|
|
||||||
|
/* Miscellaneous info on the connection. */
|
||||||
|
unsigned long client_pid;
|
||||||
|
int client_uid;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* This is a special version of the usual _() gettext macro. It
|
||||||
|
* assumes a server connection control variable with the name "ctrl"
|
||||||
|
* and uses that to translate a string according to the locale set for
|
||||||
|
* the connection. The macro LunderscoreIMPL is used by i18n to
|
||||||
|
* actually define the inline function when needed. */
|
||||||
|
#if defined (ENABLE_NLS) || defined (USE_SIMPLE_GETTEXT)
|
||||||
|
#define L_(a) keyboxd_Lunderscore (ctrl, (a))
|
||||||
|
#define LunderscorePROTO \
|
||||||
|
static inline const char *keyboxd_Lunderscore (ctrl_t ctrl, \
|
||||||
|
const char *string) \
|
||||||
|
GNUPG_GCC_ATTR_FORMAT_ARG(2);
|
||||||
|
#define LunderscoreIMPL \
|
||||||
|
static inline const char * \
|
||||||
|
keyboxd_Lunderscore (ctrl_t ctrl, const char *string) \
|
||||||
|
{ \
|
||||||
|
return ctrl? i18n_localegettext (ctrl->lc_messages, string) \
|
||||||
|
/* */: gettext (string); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define L_(a) (a)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*-- keyboxd.c --*/
|
||||||
|
void kbxd_exit (int rc) GPGRT_ATTR_NORETURN;
|
||||||
|
void kbxd_set_progress_cb (void (*cb)(ctrl_t ctrl, const char *what,
|
||||||
|
int printchar, int current, int total),
|
||||||
|
ctrl_t ctrl);
|
||||||
|
const char *get_kbxd_socket_name (void);
|
||||||
|
int get_kbxd_active_connection_count (void);
|
||||||
|
void kbxd_sighup_action (void);
|
||||||
|
|
||||||
|
|
||||||
|
/*-- kbxserver.c --*/
|
||||||
|
void kbxd_start_command_handler (ctrl_t, gnupg_fd_t, unsigned int);
|
||||||
|
|
||||||
|
#endif /*KEYBOXD_H*/
|
Loading…
x
Reference in New Issue
Block a user