common: Consolidate Assuan server argument handling.

* common/Makefile.am (common_sources): Add new files.
* common/server-help.c: New file.
* common/server-help.h: Likewise.
* agent/command.c: Drop argument handling primitives in favor of using
the consolidated ones.
* dirmngr/server.c: Likewise.
* g10/server.c: Likewise.
* g13/server.c: Likewise.
* scd/command.c: Likewise.
* sm/server.c: Likewise.

Signed-off-by: Justus Winter <justus@g10code.com>
This commit is contained in:
Justus Winter 2016-03-02 14:14:33 +01:00
parent 9a1778abca
commit e77c85577d
9 changed files with 207 additions and 298 deletions

View File

@ -41,6 +41,7 @@
#include "cvt-openpgp.h"
#include "../common/ssh-utils.h"
#include "../common/asshelp.h"
#include "../common/server-help.h"
/* Maximum allowed size of the inquired ciphertext. */
@ -229,86 +230,6 @@ reset_notify (assuan_context_t ctx, char *line)
}
/* Skip over options in LINE.
Blanks after the options are also removed. Options are indicated
by two leading dashes followed by a string consisting of non-space
characters. The special option "--" indicates an explicit end of
options; all what follows will not be considered an option. The
first no-option string also indicates the end of option parsing. */
static char *
skip_options (const char *line)
{
while (spacep (line))
line++;
while ( *line == '-' && line[1] == '-' )
{
while (*line && !spacep (line))
line++;
while (spacep (line))
line++;
}
return (char*)line;
}
/* Check whether the option NAME appears in LINE. An example for a
line with options is:
--algo=42 --data foo bar
This function would then only return true if NAME is "data". */
static int
has_option (const char *line, const char *name)
{
const char *s;
int n = strlen (name);
s = strstr (line, name);
if (s && s >= skip_options (line))
return 0;
return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
}
/* Same as has_option but does only test for the name of the option
and ignores an argument, i.e. with NAME being "--hash" it would
return true for "--hash" as well as for "--hash=foo". */
static int
has_option_name (const char *line, const char *name)
{
const char *s;
int n = strlen (name);
s = strstr (line, name);
if (s && s >= skip_options (line))
return 0;
return (s && (s == line || spacep (s-1))
&& (!s[n] || spacep (s+n) || s[n] == '='));
}
/* Return a pointer to the argument of the option with NAME. If such
an option is not given, NULL is retruned. */
static char *
option_value (const char *line, const char *name)
{
char *s;
int n = strlen (name);
s = strstr (line, name);
if (s && s >= skip_options (line))
return NULL;
if (s && (s == line || spacep (s-1))
&& s[n] && (spacep (s+n) || s[n] == '='))
{
s += n + 1;
s += strspn (s, " ");
if (*s && !spacep(s))
return s;
}
return NULL;
}
/* Replace all '+' by a blank in the string S. */
static void
plus_to_blank (char *s)

View File

@ -88,7 +88,8 @@ common_sources = \
mkdir_p.c mkdir_p.h \
strlist.c strlist.h \
call-gpg.c call-gpg.h \
exectool.c exectool.h
exectool.c exectool.h \
server-help.c server-help.h
if HAVE_W32_SYSTEM
common_sources += w32-reg.c w32-afunix.c w32-afunix.h

137
common/server-help.c Normal file
View File

@ -0,0 +1,137 @@
/* server-help.h - Helper functions for writing Assuan servers.
* Copyright (C) 2003, 2009, 2010 g10 Code GmbH
*
* This file is part of GnuPG.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either
*
* - the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at
* your option) any later version.
*
* or
*
* - 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.
*
* or both in parallel, as here.
*
* This file 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 <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <string.h>
#include "server-help.h"
#include "util.h"
/* Skip over options in LINE.
Blanks after the options are also removed. Options are indicated
by two leading dashes followed by a string consisting of non-space
characters. The special option "--" indicates an explicit end of
options; all what follows will not be considered an option. The
first no-option string also indicates the end of option parsing. */
char *
skip_options (const char *line)
{
while (spacep (line))
line++;
while (*line == '-' && line[1] == '-')
{
while (*line && !spacep (line))
line++;
while (spacep (line))
line++;
}
return (char*) line;
}
/* Check whether the option NAME appears in LINE. */
int
has_option (const char *line, const char *name)
{
const char *s;
int n = strlen (name);
s = strstr (line, name);
if (s && s >= skip_options (line))
return 0;
return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
}
/* Same as has_option but only considers options at the begin of the
line. This is useful for commands which allow arbitrary strings on
the line. */
int
has_leading_option (const char *line, const char *name)
{
const char *s;
int n;
if (name[0] != '-' || name[1] != '-' || !name[2] || spacep (name+2))
return 0;
n = strlen (name);
while ( *line == '-' && line[1] == '-' )
{
s = line;
while (*line && !spacep (line))
line++;
if (n == (line - s) && !strncmp (s, name, n))
return 1;
while (spacep (line))
line++;
}
return 0;
}
/* Same as has_option but does only test for the name of the option
and ignores an argument, i.e. with NAME being "--hash" it would
return a pointer for "--hash" as well as for "--hash=foo". If
there is no such option NULL is returned. The pointer returned
points right behind the option name, this may be an equal sign, Nul
or a space. */
const char *
has_option_name (const char *line, const char *name)
{
const char *s;
int n = strlen (name);
s = strstr (line, name);
return (s && (s == line || spacep (s-1))
&& (!s[n] || spacep (s+n) || s[n] == '=')) ? (s+n) : NULL;
}
/* Return a pointer to the argument of the option with NAME. If such
an option is not given, NULL is returned. */
char *
option_value (const char *line, const char *name)
{
char *s;
int n = strlen (name);
s = strstr (line, name);
if (s && s >= skip_options (line))
return NULL;
if (s && (s == line || spacep (s-1))
&& s[n] && (spacep (s+n) || s[n] == '='))
{
s += n + 1;
s += strspn (s, " ");
if (*s && !spacep(s))
return s;
}
return NULL;
}

62
common/server-help.h Normal file
View File

@ -0,0 +1,62 @@
/* server-help.h - Helper functions for writing Assuan servers.
* Copyright (C) 2003, 2009, 2010 g10 Code GmbH
*
* This file is part of GnuPG.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either
*
* - the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at
* your option) any later version.
*
* or
*
* - 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.
*
* or both in parallel, as here.
*
* This file 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 <http://www.gnu.org/licenses/>.
*/
#ifndef GNUPG_COMMON_SERVER_HELP_H
#define GNUPG_COMMON_SERVER_HELP_H
/* Skip over options in LINE.
Blanks after the options are also removed. Options are indicated
by two leading dashes followed by a string consisting of non-space
characters. The special option "--" indicates an explicit end of
options; all what follows will not be considered an option. The
first no-option string also indicates the end of option parsing. */
char *skip_options (const char *line);
/* Check whether the option NAME appears in LINE. */
int has_option (const char *line, const char *name);
/* Same as has_option but only considers options at the begin of the
line. This is useful for commands which allow arbitrary strings on
the line. */
int has_leading_option (const char *line, const char *name);
/* Same as has_option but does only test for the name of the option
and ignores an argument, i.e. with NAME being "--hash" it would
return a pointer for "--hash" as well as for "--hash=foo". If
there is no such option NULL is returned. The pointer returned
points right behind the option name, this may be an equal sign, Nul
or a space. */
const char *has_option_name (const char *line, const char *name);
/* Return a pointer to the argument of the option with NAME. If such
an option is not given, NULL is returned. */
char *option_value (const char *line, const char *name);
#endif /* GNUPG_COMMON_SERVER_HELP_H */

View File

@ -53,6 +53,7 @@
#include "dns-stuff.h"
#include "mbox-util.h"
#include "zb32.h"
#include "server-help.h"
/* To avoid DoS attacks we limit the size of a certificate to
something reasonable. The DoS was actually only an issue back when
@ -273,78 +274,6 @@ strcpy_escaped_plus (char *d, const unsigned char *s)
}
/* Check whether the option NAME appears in LINE */
static int
has_option (const char *line, const char *name)
{
const char *s;
int n = strlen (name);
s = strstr (line, name);
return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
}
/* Same as has_option but only considers options at the begin of the
line. This is useful for commands which allow arbitrary strings on
the line. */
static int
has_leading_option (const char *line, const char *name)
{
const char *s;
int n;
if (name[0] != '-' || name[1] != '-' || !name[2] || spacep (name+2))
return 0;
n = strlen (name);
while ( *line == '-' && line[1] == '-' )
{
s = line;
while (*line && !spacep (line))
line++;
if (n == (line - s) && !strncmp (s, name, n))
return 1;
while (spacep (line))
line++;
}
return 0;
}
/* Same as has_option but does only test for the name of the option
and ignores an argument, i.e. with NAME being "--hash" it would
return a pointer for "--hash" as well as for "--hash=foo". If
thhere is no such option NULL is returned. The pointer returned
points right behind the option name, this may be an equal sign, Nul
or a space. */
/* static const char * */
/* has_option_name (const char *line, const char *name) */
/* { */
/* const char *s; */
/* int n = strlen (name); */
/* s = strstr (line, name); */
/* return (s && (s == line || spacep (s-1)) */
/* && (!s[n] || spacep (s+n) || s[n] == '=')) ? (s+n) : NULL; */
/* } */
/* Skip over options. It is assumed that leading spaces have been
removed (this is the case for lines passed to a handler from
assuan). Blanks after the options are also removed. */
static char *
skip_options (char *line)
{
while ( *line == '-' && line[1] == '-' )
{
while (*line && !spacep (line))
line++;
while (spacep (line))
line++;
}
return line;
}
/* This fucntion returns true if a Tor server is running. The sattus
is cached for the current conenction. */
static int

View File

@ -32,6 +32,7 @@
#include "util.h"
#include "i18n.h"
#include "options.h"
#include "../common/server-help.h"
#include "../common/sysutils.h"
#include "status.h"
@ -68,40 +69,6 @@ close_message_fd (ctrl_t ctrl)
}
}
/* Skip over options. Blanks after the options are also removed. */
static char *
skip_options (const char *line)
{
while (spacep (line))
line++;
while ( *line == '-' && line[1] == '-' )
{
while (*line && !spacep (line))
line++;
while (spacep (line))
line++;
}
return (char*)line;
}
/* Check whether the option NAME appears in LINE. */
static int
has_option (const char *line, const char *name)
{
const char *s;
int n = strlen (name);
s = strstr (line, name);
if (s && s >= skip_options (line))
return 0;
return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
}
/* Called by libassuan for Assuan options. See the Assuan manual for
details. */

View File

@ -33,7 +33,7 @@
#include "create.h"
#include "mount.h"
#include "suspend.h"
#include "../common/server-help.h"
/* The filepointer for status message used in non-server mode */
static FILE *statusfp;
@ -65,37 +65,6 @@ static int command_has_option (const char *cmd, const char *cmdopt);
#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
/* Skip over options. Blanks after the options are also removed. */
static char *
skip_options (const char *line)
{
while (spacep (line))
line++;
while ( *line == '-' && line[1] == '-' )
{
while (*line && !spacep (line))
line++;
while (spacep (line))
line++;
}
return (char*)line;
}
/* Check whether the option NAME appears in LINE. */
/* static int */
/* has_option (const char *line, const char *name) */
/* { */
/* const char *s; */
/* int n = strlen (name); */
/* s = strstr (line, name); */
/* if (s && s >= skip_options (line)) */
/* return 0; */
/* return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); */
/* } */
/* Helper to print a message while leaving a command. */
static gpg_error_t
leave_cmd (assuan_context_t ctx, gpg_error_t err)

View File

@ -42,6 +42,7 @@
#include "ccid-driver.h"
#endif
#include "asshelp.h"
#include "server-help.h"
/* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
#define MAXLEN_PIN 100
@ -219,53 +220,6 @@ update_card_removed (int vrdr, int value)
}
/* Check whether the option NAME appears in LINE. Returns 1 or 0. */
static int
has_option (const char *line, const char *name)
{
const char *s;
int n = strlen (name);
s = strstr (line, name);
return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
}
/* Same as has_option but does only test for the name of the option
and ignores an argument, i.e. with NAME being "--hash" it would
return a pointer for "--hash" as well as for "--hash=foo". If
there is no such option NULL is returned. The pointer returned
points right behind the option name, this may be an equal sign, Nul
or a space. */
static const char *
has_option_name (const char *line, const char *name)
{
const char *s;
int n = strlen (name);
s = strstr (line, name);
return (s && (s == line || spacep (s-1))
&& (!s[n] || spacep (s+n) || s[n] == '=')) ? (s+n) : NULL;
}
/* Skip over options. It is assumed that leading spaces have been
removed (this is the case for lines passed to a handler from
assuan). Blanks after the options are also removed. */
static char *
skip_options (char *line)
{
while ( *line == '-' && line[1] == '-' )
{
while (*line && !spacep (line))
line++;
while (spacep (line))
line++;
}
return line;
}
/* Convert the STRING into a newly allocated buffer while translating
the hex numbers. Stops at the first invalid character. Blanks and
colons are allowed to separate the hex digits. Returns NULL on

View File

@ -30,6 +30,7 @@
#include "gpgsm.h"
#include <assuan.h>
#include "sysutils.h"
#include "server-help.h"
#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
@ -95,38 +96,6 @@ strcpy_escaped_plus (char *d, const char *s)
}
/* Skip over options.
Blanks after the options are also removed. */
static char *
skip_options (const char *line)
{
while (spacep (line))
line++;
while ( *line == '-' && line[1] == '-' )
{
while (*line && !spacep (line))
line++;
while (spacep (line))
line++;
}
return (char*)line;
}
/* Check whether the option NAME appears in LINE */
static int
has_option (const char *line, const char *name)
{
const char *s;
int n = strlen (name);
s = strstr (line, name);
if (s && s >= skip_options (line))
return 0;
return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
}
/* A write handler used by es_fopencookie to write assuan data
lines. */
static gpgrt_ssize_t