📄 pgpconf.c
字号:
/*____________________________________________________________________________
Copyright (C) 1997 Network Associates Inc. and affiliated companies.
All rights reserved.
$Id: pgpConf.c,v 1.15.8.1 1999/06/04 00:28:49 heller Exp $
____________________________________________________________________________*/
#include "pgpConfig.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h> /* For strtol() */
#include <string.h>
#include "pgpConf.h"
#include "pgpEnv.h"
#include "pgpErrors.h"
#include "pgpMsg.h"
#include "pgpUI.h"
typedef struct Config
{
char const *name;
int var;
unsigned flags;
int min, max;
} Config;
/* The following are in the flags: */
#define OPT_TYPEMASK 3
#define OPT_IGNORE 0 /* Ignore if encountered */
#define OPT_BINARY 1 /* PGPBoolean options: min = false, max = true */
#define OPT_INT 2 /* Integer option, in range [min,max] */
#define OPT_STRING 3 /* String, of length <= max */
/* The following additional flags are also used: */
#define OPT_CMD 4 /* Command line only */
#define OPT_LOWER 8 /* Lowercase strings before storing */
#define OPT_FUNC 16 /* Call function rather than set conf */
/* Up to this many errors are ignored when reading a config file. */
#define MAX_ERRORS 3 /* Don't give up right away on error. */
#define FUNC_RANDSOURCE 2
/* The options list. Indexes in the left margin are used in configInit. */
static Config
EnvOptions[] = {
{ "armor", PGPENV_ARMOR, OPT_BINARY, 0, 1 },
{ "armorlines", PGPENV_ARMORLINES, OPT_INT, 0, INT_MAX },
{ "bakring", PGPENV_BAKRING, OPT_STRING, 0, 0 },
{ "cert_depth", PGPENV_CERTDEPTH, OPT_INT, 0, 8 },
{ "charset", PGPENV_CHARSET, OPT_STRING, 0, 0 },
{ "clearsig", PGPENV_CLEARSIG, OPT_BINARY, 0, 1 },
{ "comment", PGPENV_COMMENT, OPT_STRING, 0, 70 },
{ "completes_needed", PGPENV_COMPLETES, OPT_INT, 1, 4 },
{ "compress", PGPENV_COMPRESS, OPT_BINARY, 0, 1 },
{ "companykey", PGPENV_COMPANYKEY, OPT_STRING, 0, 255 },
{ "encrypttoself", PGPENV_ENCRYPTTOSELF,OPT_BINARY, 0, 1 },
/* { "interactive", PGPENV_INTERACTIVE, OPT_BINARY, 0, 1 },*/
/* { "keepbinary", PGPENV_KEEPBINARY, OPT_BINARY, 0, 1 },*/
{ "language", PGPENV_LANGUAGE, OPT_STRING|OPT_LOWER, 0, 16 },
{ "marginals_needed", PGPENV_MARGINALS, OPT_INT, 1, 4 },
{ "myname", PGPENV_MYNAME, OPT_STRING, 0, 255 },
/* { "pager", PGPENV_PAGER, OPT_STRING, 0, 255 },*/
/* { "pkcs_compat", PGPENV_PKCS_COMPAT, OPT_INT, 0, INT_MAX },*/
{ "pgp_mime", PGPENV_PGPMIME, OPT_BINARY, 0, 1 },
{ "pgp_mimeparse", PGPENV_PGPMIMEPARSEBODY, OPT_BINARY,0, 1 },
{ "pubring", PGPENV_PUBRINGnolongerused, OPT_STRING,0, 0 },
{ "randomdevice", PGPENV_RANDOMDEVICE, OPT_STRING, 0, 0 },
{ "randseed", PGPENV_RANDSEEDnolongerused, OPT_STRING, 0, 0 },
#if PGP_UNIX
/* { "randsource", FUNC_RANDSOURCE, OPT_STRING|OPT_FUNC, 0, 0 },*/
#endif
{ "secring", PGPENV_SECRINGnolongerused, OPT_STRING, 0, 0 },
{ "showpass", PGPENV_SHOWPASS, OPT_BINARY, 0, 1 },
{ "textmode", PGPENV_TEXTMODE, OPT_BINARY, 0, 1 },
{ "tmp", PGPENV_TMP, OPT_STRING, 0, 0 },
/* Temp for new trust - change to something better */
{ "trusted", PGPENV_TRUSTED, OPT_INT, 0, 255 },
{ "tzfix", PGPENV_TZFIX, OPT_INT, -24, 24 },
{ "verbose", PGPENV_VERBOSE, OPT_INT, 0, INT_MAX },
/* Experimental XXX@@@ */
{ "version", PGPENV_VERSION, OPT_INT, 2, 4 },
{ "ciphernum", PGPENV_CIPHER, OPT_INT, 1, INT_MAX },
{ "hashnum", PGPENV_HASH, OPT_INT, 1, INT_MAX },
{ "fastkeygen", PGPENV_FASTKEYGEN, OPT_BINARY, 0, 1 },
/* command line only */
{ "batchmode", PGPENV_BATCHMODE, OPT_BINARY|OPT_CMD, 0, 1 },
{ "force", PGPENV_FORCE, OPT_BINARY|OPT_CMD, 0, 1 },
{ "magic", PGPENV_MAGIC, OPT_BINARY|OPT_CMD, 0, 1 },
{ "noout", PGPENV_NOOUT, OPT_BINARY|OPT_CMD, 0, 1 },
/* Null-terminated */
{ (char const *)0, 0, 0, 0, 0 }
};
/* Case-insensitive memory compare */
static int
xmemicmp (char const *in1, char const *in2, int len)
{
while (len--) {
if (tolower(*in1) != tolower(*in2))
return 1;
in1++;
in2++;
}
return 0;
}
/*
* Find a keyword in a null-terminated options list.
* Returns the option, or NULL if the option is ambiguous,
* or a pointer to the null option if it is not found.
* optmask is a mask of bits in the opt->flags list which cause
* entries with any of those bits set to be ignored.
*/
static Config const *
configLookup (PGPUICb const *ui, void *arg, unsigned linenum,
char const *key, unsigned keylen, int optmask)
{
Config *hit = NULL;
int i;
PgpUICbArg msgarg1, msgarg2, msgarg3, msgarg4;
for (i=0; EnvOptions[i].name; i++) {
if ((EnvOptions[i].flags & optmask) != 0)
continue;
if (xmemicmp(EnvOptions[i].name, key, keylen) != 0)
continue;
/* We have a match! */
if (strlen(EnvOptions[i].name) == keylen)
return (&(EnvOptions[i])); /* exact match */
/* Do we have a double match? */
if (hit) {
msgarg1.type = PGP_UI_ARG_UNSIGNED;
msgarg1.val.u = linenum;
msgarg2.type = PGP_UI_ARG_BUFFER;
msgarg2.val.buf.buf = (PGPByte *)key;
msgarg2.val.buf.len = keylen;
msgarg3.type = PGP_UI_ARG_STRING;
msgarg3.val.s = hit->name;
msgarg4.type = PGP_UI_ARG_STRING;
msgarg4.val.s = EnvOptions[i].name;
ui->message (arg, kPGPError_ConfigParseFailure,
PGPMSG_CONFIG_AMBIGUOUS, 4, &msgarg1,
&msgarg2, &msgarg3, &msgarg4);
return (Config const *)0;
}
/* Remember this match */
hit = &(EnvOptions[i]);
/* Keep looking for an exact match or ambiguity. */
}
if (hit) {
return hit;
}
msgarg1.type = PGP_UI_ARG_UNSIGNED;
msgarg1.val.u = linenum;
msgarg2.type = PGP_UI_ARG_BUFFER;
msgarg2.val.buf.buf = (PGPByte *)key;
msgarg2.val.buf.len = keylen;
ui->message (arg, kPGPError_ConfigParseFailure,
PGPMSG_CONFIG_UNKNOWN_KEYWORD,
2, &msgarg1, &msgarg2);
return (&EnvOptions[i]);
}
static int
configCallFunci (PGPEnv *env, int varnum, int val, int pri)
{
(void)env;
(void)val;
(void)pri;
switch (varnum) {
default:
return kPGPError_ConfigParseFailureBadFunction;
}
}
static int
configCallFuncs (PGPEnv *env, int varnum, char const *string, int len,
int pri)
{
(void)env;
(void)string;
(void)len;
(void)pri;
switch (varnum) {
case FUNC_RANDSOURCE:
default:
return kPGPError_ConfigParseFailureBadFunction;
}
}
/* Return the number of leading whitespace characters in a buffer */
static unsigned
skipWhite(char const *buf)
{
unsigned i = 0;
while (isspace((int) buf[i]))
i++;
return i;
}
/*
* Reduce "len" by the amount of trailing whitespace characters in the
* string starting at buf and len characters long.
*/
static unsigned
unskipWhite(char const *buf, unsigned len)
{
while (len && isspace((int) buf[len-1]))
--len;
return len;
}
/*
* Get a word up to the next non-graphic character, comment symbol (#)
* or delimiter (such as '='). Set delimiter to a non-graphic character
* (0 works well) to not use it.
* Returns the length of the word found.
*/
static unsigned
getWord(char const *buf, char delimiter)
{
char c;
int i = 0;
do {
c = buf[i++];
} while (isgraph((int) c) && c != '#' && c != delimiter);
return i-1;
}
/*
* Get a string in the nasty non-quoted format.
* Spaces are allowed, but the string ends at a comment and
* trailing whitespace is suppresed.
* Returns the length of the string found.
*/
static unsigned
getString(char const *buf)
{
char c;
unsigned i = 0;
do
c = buf[i++];
while (isprint((int) c) && c != '#');
return unskipWhite(buf, i-1);
}
/*
* Get a quoted string. Anything is allowed up to a trailing double
* quote. Returns the length of the string found, or -1 on error.
*/
static unsigned
getQString(PGPUICb const *ui, void *arg, unsigned linenum,
char const *buf)
{
char c;
unsigned i = 0;
PgpUICbArg msgarg1, msgarg2;
do
c = buf[i++];
while (c && c != '"');
--i;
if (c == '"')
return i;
/* Error case - drop trailing whitespace (like NL) when printing */
msgarg1.type = PGP_UI_ARG_UNSIGNED;
msgarg1.val.u = linenum;
msgarg2.type = PGP_UI_ARG_BUFFER;
msgarg2.val.buf.buf = (PGPByte *)buf;
msgarg2.val.buf.len = unskipWhite (buf, i);
ui->message (arg, kPGPError_ConfigParseFailure, PGPMSG_CONFIG_STRINGEND,
2, &msgarg1, &msgarg2);
return (unsigned)-1;
}
/*
* Parse a line of input. linenum == 0 indicates the command line,
* and causes a few changes in activity:
* - some extra parameters are recognized (OPT_CMD)
* - "=ON" is implicit for boolean options
* - error messages are printed differently
* - Unknown keywords are fatal
* - Strings need not be copied, since the argv array isn't going away
*
* Note that the input "line" array is not permanently modified, but it
* is occasionally modified in place temporarily to install a trailing
* null character in the middle.
*
* Returns 0 on success, a kPGPError_* on failure.
*/
static int
configLineParse(PGPUICb const *ui, void *arg, PGPEnv *env,
unsigned linenum, char *line, int pri)
{
char const *key;
unsigned keylen;
unsigned i;
Config const *opt;
long val;
char *p;
PgpUICbArg msgarg1, msgarg2, msgarg3, msgarg4, msgarg5;
line += skipWhite (line);
keylen = getWord (line, '=');
if (!keylen)
return 0; /* Blank line */
key = line;
opt = configLookup (ui, arg, linenum, key, keylen,
linenum ? OPT_CMD : 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -