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 "cvt-openpgp.h"
#include "../common/ssh-utils.h" #include "../common/ssh-utils.h"
#include "../common/asshelp.h" #include "../common/asshelp.h"
#include "../common/server-help.h"
/* Maximum allowed size of the inquired ciphertext. */ /* 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. */ /* Replace all '+' by a blank in the string S. */
static void static void
plus_to_blank (char *s) plus_to_blank (char *s)

View File

@ -88,7 +88,8 @@ common_sources = \
mkdir_p.c mkdir_p.h \ mkdir_p.c mkdir_p.h \
strlist.c strlist.h \ strlist.c strlist.h \
call-gpg.c call-gpg.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 if HAVE_W32_SYSTEM
common_sources += w32-reg.c w32-afunix.c w32-afunix.h 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 "dns-stuff.h"
#include "mbox-util.h" #include "mbox-util.h"
#include "zb32.h" #include "zb32.h"
#include "server-help.h"
/* To avoid DoS attacks we limit the size of a certificate to /* To avoid DoS attacks we limit the size of a certificate to
something reasonable. The DoS was actually only an issue back when 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 /* This fucntion returns true if a Tor server is running. The sattus
is cached for the current conenction. */ is cached for the current conenction. */
static int static int

View File

@ -32,6 +32,7 @@
#include "util.h" #include "util.h"
#include "i18n.h" #include "i18n.h"
#include "options.h" #include "options.h"
#include "../common/server-help.h"
#include "../common/sysutils.h" #include "../common/sysutils.h"
#include "status.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 /* Called by libassuan for Assuan options. See the Assuan manual for
details. */ details. */

View File

@ -33,7 +33,7 @@
#include "create.h" #include "create.h"
#include "mount.h" #include "mount.h"
#include "suspend.h" #include "suspend.h"
#include "../common/server-help.h"
/* The filepointer for status message used in non-server mode */ /* The filepointer for status message used in non-server mode */
static FILE *statusfp; 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)) #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. */ /* Helper to print a message while leaving a command. */
static gpg_error_t static gpg_error_t
leave_cmd (assuan_context_t ctx, gpg_error_t err) leave_cmd (assuan_context_t ctx, gpg_error_t err)

View File

@ -42,6 +42,7 @@
#include "ccid-driver.h" #include "ccid-driver.h"
#endif #endif
#include "asshelp.h" #include "asshelp.h"
#include "server-help.h"
/* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */ /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
#define MAXLEN_PIN 100 #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 /* Convert the STRING into a newly allocated buffer while translating
the hex numbers. Stops at the first invalid character. Blanks and the hex numbers. Stops at the first invalid character. Blanks and
colons are allowed to separate the hex digits. Returns NULL on colons are allowed to separate the hex digits. Returns NULL on

View File

@ -30,6 +30,7 @@
#include "gpgsm.h" #include "gpgsm.h"
#include <assuan.h> #include <assuan.h>
#include "sysutils.h" #include "sysutils.h"
#include "server-help.h"
#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t)) #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 /* A write handler used by es_fopencookie to write assuan data
lines. */ lines. */
static gpgrt_ssize_t static gpgrt_ssize_t