]> granicus.if.org Git - nethack/commitdiff
Secure config errors
authorPasi Kallinen <paxed@alt.org>
Sun, 10 Sep 2017 18:05:45 +0000 (21:05 +0300)
committerPasi Kallinen <paxed@alt.org>
Sun, 10 Sep 2017 18:05:51 +0000 (21:05 +0300)
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.

include/config.h
include/extern.h
src/files.c
src/options.c
sys/share/pcmain.c
sys/unix/unixmain.c

index ba5db5443b904544e123a7abbaefd589a2194d86..a8d10c67be37928ef6e38d14d640d013576f820c 100644 (file)
@@ -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
  *
index 4af9fd272d391375c639dc13097161cf057bc77b..02bb1d85feb9b7d1a2c61a6454b15bf67c5710a4 100644 (file)
@@ -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));
index 0ec9ff8c52ac8f679e99b244afce8f1f87c6b4ef..7d4278e26391780367575c6b97c7121daa309aa3 100644 (file)
@@ -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
index 59c4a236f5396d10613fc25f90c42dd5e85abd81..db512c13636d640242f877def5ec7ad47eeb07ca 100644 (file)
@@ -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();
         }
index a515541c284ea1d4ff48c691f8bb155edfffdcac..d62d234cc52aecf184d08110c167d22630c12c0a 100644 (file)
@@ -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;
index 61db447099a5668414629aa88f2ca49a9b0e9162..c106914440759e32c66f8ee3d8565f2cb197163e 100644 (file)
@@ -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;