Secure config errors
If user can make NETHACKOPTIONS point to a file, that user could then get the file contents via the extended config file error reporting. Add CONFIG_ERROR_SECURE compile-time option to make that case output only the first error, no line number or error context.
This commit is contained in:
@@ -449,6 +449,14 @@ typedef unsigned char uchar;
|
|||||||
|
|
||||||
#define DOAGAIN '\001' /* ^A, the "redo" key used in cmd.c and getline.c */
|
#define DOAGAIN '\001' /* ^A, the "redo" key used in cmd.c and getline.c */
|
||||||
|
|
||||||
|
/* CONFIG_ERROR_SECURE: If user makes NETHACKOPTIONS point to a file ...
|
||||||
|
* TRUE: Show the first error, nothing else.
|
||||||
|
* FALSE: Show all errors as normal, with line numbers and context.
|
||||||
|
*/
|
||||||
|
#ifndef CONFIG_ERROR_SECURE
|
||||||
|
# define CONFIG_ERROR_SECURE TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Section 4: EXPERIMENTAL STUFF
|
* Section 4: EXPERIMENTAL STUFF
|
||||||
*
|
*
|
||||||
|
|||||||
+1
-1
@@ -767,7 +767,7 @@ E void FDECL(unlock_file, (const char *));
|
|||||||
#ifdef USER_SOUNDS
|
#ifdef USER_SOUNDS
|
||||||
E boolean FDECL(can_read_file, (const char *));
|
E boolean FDECL(can_read_file, (const char *));
|
||||||
#endif
|
#endif
|
||||||
E void FDECL(config_error_init, (BOOLEAN_P, const char *));
|
E void FDECL(config_error_init, (BOOLEAN_P, const char *, BOOLEAN_P));
|
||||||
E void FDECL(config_error_add, (const char *, ...)) PRINTF_F(1, 2);
|
E void FDECL(config_error_add, (const char *, ...)) PRINTF_F(1, 2);
|
||||||
E int NDECL(config_error_done);
|
E int NDECL(config_error_done);
|
||||||
E boolean FDECL(read_config_file, (const char *, int));
|
E boolean FDECL(read_config_file, (const char *, int));
|
||||||
|
|||||||
+22
-9
@@ -200,7 +200,7 @@ STATIC_DCL void FDECL(set_symhandling, (char *, int));
|
|||||||
#ifdef NOCWD_ASSUMPTIONS
|
#ifdef NOCWD_ASSUMPTIONS
|
||||||
STATIC_DCL void FDECL(adjust_prefix, (char *, int));
|
STATIC_DCL void FDECL(adjust_prefix, (char *, int));
|
||||||
#endif
|
#endif
|
||||||
STATIC_DCL void FDECL(config_error_nextline, (const char *));
|
STATIC_DCL boolean FDECL(config_error_nextline, (const char *));
|
||||||
STATIC_DCL void NDECL(free_config_sections);
|
STATIC_DCL void NDECL(free_config_sections);
|
||||||
STATIC_DCL char *FDECL(choose_random_part, (char *, CHAR_P));
|
STATIC_DCL char *FDECL(choose_random_part, (char *, CHAR_P));
|
||||||
STATIC_DCL boolean FDECL(is_config_section, (const char *));
|
STATIC_DCL boolean FDECL(is_config_section, (const char *));
|
||||||
@@ -2751,18 +2751,21 @@ static int config_err_line_num = 0;
|
|||||||
static int config_err_num_errors = 0;
|
static int config_err_num_errors = 0;
|
||||||
static boolean config_err_origline_shown = FALSE;
|
static boolean config_err_origline_shown = FALSE;
|
||||||
static boolean config_err_fromfile = FALSE;
|
static boolean config_err_fromfile = FALSE;
|
||||||
|
static boolean config_err_secure = FALSE;
|
||||||
static char config_err_origline[4 * BUFSZ];
|
static char config_err_origline[4 * BUFSZ];
|
||||||
static char config_err_source[BUFSZ];
|
static char config_err_source[BUFSZ];
|
||||||
|
|
||||||
void
|
void
|
||||||
config_error_init(from_file, sourcename)
|
config_error_init(from_file, sourcename, secure)
|
||||||
boolean from_file;
|
boolean from_file;
|
||||||
const char *sourcename;
|
const char *sourcename;
|
||||||
|
boolean secure;
|
||||||
{
|
{
|
||||||
config_err_line_num = 0;
|
config_err_line_num = 0;
|
||||||
config_err_num_errors = 0;
|
config_err_num_errors = 0;
|
||||||
config_err_origline_shown = FALSE;
|
config_err_origline_shown = FALSE;
|
||||||
config_err_fromfile = from_file;
|
config_err_fromfile = from_file;
|
||||||
|
config_err_secure = secure;
|
||||||
config_err_origline[0] = '\0';
|
config_err_origline[0] = '\0';
|
||||||
if (sourcename && sourcename[0])
|
if (sourcename && sourcename[0])
|
||||||
Strcpy(config_err_source, sourcename);
|
Strcpy(config_err_source, sourcename);
|
||||||
@@ -2770,22 +2773,26 @@ const char *sourcename;
|
|||||||
config_err_source[0] = '\0';
|
config_err_source[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC_OVL void
|
STATIC_OVL boolean
|
||||||
config_error_nextline(line)
|
config_error_nextline(line)
|
||||||
const char *line;
|
const char *line;
|
||||||
{
|
{
|
||||||
|
if (config_err_num_errors && config_err_secure)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
config_err_line_num++;
|
config_err_line_num++;
|
||||||
config_err_origline_shown = FALSE;
|
config_err_origline_shown = FALSE;
|
||||||
if (line && line[0])
|
if (line && line[0])
|
||||||
Strcpy(config_err_origline, line);
|
Strcpy(config_err_origline, line);
|
||||||
else
|
else
|
||||||
config_err_origline[0] = '\0';
|
config_err_origline[0] = '\0';
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS1*/
|
/*VARARGS1*/
|
||||||
void config_error_add
|
void config_error_add
|
||||||
VA_DECL(const char *, str)
|
VA_DECL(const char *, str)
|
||||||
/*const char *errmsg;*/
|
|
||||||
{
|
{
|
||||||
VA_START(str);
|
VA_START(str);
|
||||||
VA_INIT(str, char *);
|
VA_INIT(str, char *);
|
||||||
@@ -2795,15 +2802,18 @@ VA_DECL(const char *, str)
|
|||||||
Vsprintf(buf, str, VA_ARGS);
|
Vsprintf(buf, str, VA_ARGS);
|
||||||
|
|
||||||
config_err_num_errors++;
|
config_err_num_errors++;
|
||||||
if (!config_err_origline_shown) {
|
if (!config_err_origline_shown && !config_err_secure) {
|
||||||
pline("\n%s", config_err_origline);
|
pline("\n%s", config_err_origline);
|
||||||
config_err_origline_shown = TRUE;
|
config_err_origline_shown = TRUE;
|
||||||
}
|
}
|
||||||
if (config_err_line_num > 0) {
|
if (config_err_line_num > 0 && !config_err_secure) {
|
||||||
Sprintf(lineno, "Line %i: ", config_err_line_num);
|
Sprintf(lineno, "Line %i: ", config_err_line_num);
|
||||||
} else
|
} else
|
||||||
lineno[0] = '\0';
|
lineno[0] = '\0';
|
||||||
pline(" * %s%s.", lineno, (buf && buf[0]) ? buf : "Unknown error");
|
pline("%s %s%s.",
|
||||||
|
config_err_secure ? "Error:" : " *",
|
||||||
|
lineno,
|
||||||
|
(buf && buf[0]) ? buf : "Unknown error");
|
||||||
|
|
||||||
VA_END();
|
VA_END();
|
||||||
}
|
}
|
||||||
@@ -2818,7 +2828,7 @@ config_error_done()
|
|||||||
*config_err_source ? config_err_source : configfile);
|
*config_err_source ? config_err_source : configfile);
|
||||||
wait_synch();
|
wait_synch();
|
||||||
}
|
}
|
||||||
config_error_init(FALSE, "");
|
config_error_init(FALSE, "", FALSE);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2840,7 +2850,10 @@ int src;
|
|||||||
|
|
||||||
while (fgets(buf, sizeof buf, fp)) {
|
while (fgets(buf, sizeof buf, fp)) {
|
||||||
strip_newline(buf);
|
strip_newline(buf);
|
||||||
config_error_nextline(buf);
|
if (!config_error_nextline(buf)) {
|
||||||
|
rv = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
#ifdef notyet
|
#ifdef notyet
|
||||||
/*
|
/*
|
||||||
XXX Don't call read() in parse_config_line, read as callback or reassemble
|
XXX Don't call read() in parse_config_line, read as callback or reassemble
|
||||||
|
|||||||
+5
-5
@@ -637,7 +637,7 @@ initoptions()
|
|||||||
#ifdef SYSCF_FILE
|
#ifdef SYSCF_FILE
|
||||||
/* If SYSCF_FILE is specified, it _must_ exist... */
|
/* If SYSCF_FILE is specified, it _must_ exist... */
|
||||||
assure_syscf_file();
|
assure_syscf_file();
|
||||||
config_error_init(TRUE, SYSCF_FILE);
|
config_error_init(TRUE, SYSCF_FILE, FALSE);
|
||||||
|
|
||||||
/* ... and _must_ parse correctly. */
|
/* ... and _must_ parse correctly. */
|
||||||
if (!read_config_file(SYSCF_FILE, SET_IN_SYS)) {
|
if (!read_config_file(SYSCF_FILE, SET_IN_SYS)) {
|
||||||
@@ -791,25 +791,25 @@ initoptions_finish()
|
|||||||
opts++; /* @filename */
|
opts++; /* @filename */
|
||||||
/* looks like a filename */
|
/* looks like a filename */
|
||||||
if (strlen(opts) < BUFSZ / 2) {
|
if (strlen(opts) < BUFSZ / 2) {
|
||||||
config_error_init(TRUE, opts);
|
config_error_init(TRUE, opts, CONFIG_ERROR_SECURE);
|
||||||
read_config_file(opts, SET_IN_FILE);
|
read_config_file(opts, SET_IN_FILE);
|
||||||
config_error_done();
|
config_error_done();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
config_error_init(TRUE, (char *) 0);
|
config_error_init(TRUE, (char *) 0, FALSE);
|
||||||
read_config_file((char *) 0, SET_IN_FILE);
|
read_config_file((char *) 0, SET_IN_FILE);
|
||||||
config_error_done();
|
config_error_done();
|
||||||
/* let the total length of options be long;
|
/* let the total length of options be long;
|
||||||
* parseoptions() will check each individually
|
* parseoptions() will check each individually
|
||||||
*/
|
*/
|
||||||
config_error_init(FALSE, "NETHACKOPTIONS");
|
config_error_init(FALSE, "NETHACKOPTIONS", FALSE);
|
||||||
(void) parseoptions(opts, TRUE, FALSE);
|
(void) parseoptions(opts, TRUE, FALSE);
|
||||||
config_error_done();
|
config_error_done();
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
config_error_init(TRUE, (char *) 0);
|
config_error_init(TRUE, (char *) 0, FALSE);
|
||||||
read_config_file((char *) 0, SET_IN_FILE);
|
read_config_file((char *) 0, SET_IN_FILE);
|
||||||
config_error_done();
|
config_error_done();
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -776,7 +776,7 @@ char *argv[];
|
|||||||
NHWinMainInit();
|
NHWinMainInit();
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
config_error_init(FALSE, "command line");
|
config_error_init(FALSE, "command line", FALSE);
|
||||||
choose_windows(&argv[0][2]);
|
choose_windows(&argv[0][2]);
|
||||||
config_error_done();
|
config_error_done();
|
||||||
break;
|
break;
|
||||||
|
|||||||
+1
-1
@@ -405,7 +405,7 @@ char *argv[];
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'w': /* windowtype */
|
case 'w': /* windowtype */
|
||||||
config_error_init(FALSE, "command line");
|
config_error_init(FALSE, "command line", FALSE);
|
||||||
choose_windows(&argv[0][2]);
|
choose_windows(&argv[0][2]);
|
||||||
config_error_done();
|
config_error_done();
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user