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:
Pasi Kallinen
2017-09-10 21:05:51 +03:00
parent 0d24113577
commit 9c118b5b6b
6 changed files with 38 additions and 17 deletions
+8
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;