From: Pasi Kallinen Date: Sun, 10 Sep 2017 18:05:45 +0000 (+0300) Subject: Secure config errors X-Git-Tag: NetHack-3.6.1_RC01~382 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9c118b5b6b64add187c08b5e3d88ea5beca2e4c8;p=nethack 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. --- diff --git a/include/config.h b/include/config.h index ba5db5443..a8d10c67b 100644 --- a/include/config.h +++ b/include/config.h @@ -449,6 +449,14 @@ typedef unsigned char uchar; #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 * diff --git a/include/extern.h b/include/extern.h index 4af9fd272..02bb1d85f 100644 --- a/include/extern.h +++ b/include/extern.h @@ -767,7 +767,7 @@ E void FDECL(unlock_file, (const char *)); #ifdef USER_SOUNDS E boolean FDECL(can_read_file, (const char *)); #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 int NDECL(config_error_done); E boolean FDECL(read_config_file, (const char *, int)); diff --git a/src/files.c b/src/files.c index 0ec9ff8c5..7d4278e26 100644 --- a/src/files.c +++ b/src/files.c @@ -200,7 +200,7 @@ STATIC_DCL void FDECL(set_symhandling, (char *, int)); #ifdef NOCWD_ASSUMPTIONS STATIC_DCL void FDECL(adjust_prefix, (char *, int)); #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 char *FDECL(choose_random_part, (char *, CHAR_P)); 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 boolean config_err_origline_shown = FALSE; static boolean config_err_fromfile = FALSE; +static boolean config_err_secure = FALSE; static char config_err_origline[4 * BUFSZ]; static char config_err_source[BUFSZ]; void -config_error_init(from_file, sourcename) +config_error_init(from_file, sourcename, secure) boolean from_file; const char *sourcename; +boolean secure; { config_err_line_num = 0; config_err_num_errors = 0; config_err_origline_shown = FALSE; config_err_fromfile = from_file; + config_err_secure = secure; config_err_origline[0] = '\0'; if (sourcename && sourcename[0]) Strcpy(config_err_source, sourcename); @@ -2770,22 +2773,26 @@ const char *sourcename; config_err_source[0] = '\0'; } -STATIC_OVL void +STATIC_OVL boolean config_error_nextline(line) const char *line; { + if (config_err_num_errors && config_err_secure) + return FALSE; + config_err_line_num++; config_err_origline_shown = FALSE; if (line && line[0]) Strcpy(config_err_origline, line); else config_err_origline[0] = '\0'; + + return TRUE; } /*VARARGS1*/ void config_error_add VA_DECL(const char *, str) -/*const char *errmsg;*/ { VA_START(str); VA_INIT(str, char *); @@ -2795,15 +2802,18 @@ VA_DECL(const char *, str) Vsprintf(buf, str, VA_ARGS); config_err_num_errors++; - if (!config_err_origline_shown) { + if (!config_err_origline_shown && !config_err_secure) { pline("\n%s", config_err_origline); 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); } else 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(); } @@ -2818,7 +2828,7 @@ config_error_done() *config_err_source ? config_err_source : configfile); wait_synch(); } - config_error_init(FALSE, ""); + config_error_init(FALSE, "", FALSE); return n; } @@ -2840,7 +2850,10 @@ int src; while (fgets(buf, sizeof buf, fp)) { strip_newline(buf); - config_error_nextline(buf); + if (!config_error_nextline(buf)) { + rv = FALSE; + break; + } #ifdef notyet /* XXX Don't call read() in parse_config_line, read as callback or reassemble diff --git a/src/options.c b/src/options.c index 59c4a236f..db512c136 100644 --- a/src/options.c +++ b/src/options.c @@ -637,7 +637,7 @@ initoptions() #ifdef SYSCF_FILE /* If SYSCF_FILE is specified, it _must_ exist... */ assure_syscf_file(); - config_error_init(TRUE, SYSCF_FILE); + config_error_init(TRUE, SYSCF_FILE, FALSE); /* ... and _must_ parse correctly. */ if (!read_config_file(SYSCF_FILE, SET_IN_SYS)) { @@ -791,25 +791,25 @@ initoptions_finish() opts++; /* @filename */ /* looks like a filename */ 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); config_error_done(); } } else { - config_error_init(TRUE, (char *) 0); + config_error_init(TRUE, (char *) 0, FALSE); read_config_file((char *) 0, SET_IN_FILE); config_error_done(); /* let the total length of options be long; * parseoptions() will check each individually */ - config_error_init(FALSE, "NETHACKOPTIONS"); + config_error_init(FALSE, "NETHACKOPTIONS", FALSE); (void) parseoptions(opts, TRUE, FALSE); config_error_done(); } } else #endif { - config_error_init(TRUE, (char *) 0); + config_error_init(TRUE, (char *) 0, FALSE); read_config_file((char *) 0, SET_IN_FILE); config_error_done(); } diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index a515541c2..d62d234cc 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -776,7 +776,7 @@ char *argv[]; NHWinMainInit(); } */ - config_error_init(FALSE, "command line"); + config_error_init(FALSE, "command line", FALSE); choose_windows(&argv[0][2]); config_error_done(); break; diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 61db44709..c10691444 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -405,7 +405,7 @@ char *argv[]; } break; case 'w': /* windowtype */ - config_error_init(FALSE, "command line"); + config_error_init(FALSE, "command line", FALSE); choose_windows(&argv[0][2]); config_error_done(); break;