diff arogue5/options.c @ 66:c56f672244f4

arogue5: close security holes. Prevent whoami (player name), file_name, and score_file from being changed if the systemwide save location is being used.
author elwin
date Sat, 11 Aug 2012 16:27:20 +0000
parents 0ed67132cf10
children c49f7927b0fa
line wrap: on
line diff
--- a/arogue5/options.c	Fri Aug 10 21:17:14 2012 +0000
+++ b/arogue5/options.c	Sat Aug 11 16:27:20 2012 +0000
@@ -38,6 +38,7 @@
 	get_bool(),
 	put_str(),
 	get_str(),
+	get_restr(),
 	put_abil(),
 	get_abil(),
 	get_quest(),
@@ -57,19 +58,34 @@
     {"pickup", "Pick things up automatically: ",
 		(int *) &auto_pickup,	put_bool,	get_bool	},
     {"name",	 "Name: ",
-		(int *) whoami,		put_str,	get_str		},
+		(int *) whoami,		put_str,	get_restr	},
     {"fruit",	 "Fruit: ",
 		(int *) fruit,		put_str,	get_str		},
     {"file",	 "Save file: ",
-		(int *) file_name,	put_str,	get_str		},
+		(int *) file_name,	put_str,	get_restr	},
     {"score",	 "Score file: ",
-		(int *) score_file,	put_str,	get_str		},
+		(int *) score_file,	put_str,	get_restr	},
     {"class",	"Character class: ",
 		(int *)&char_type,	put_abil,	get_abil	},
     {"quest",	"Quest item: ",
 		(int *) &quest_item,	put_quest,	get_quest	}
 };
 
+/* For fields that would be restricted if use_savedir is set. */
+int get_restr(char *optstr, WINDOW *win)
+{
+    int oy, ox;
+
+    if (use_savedir)
+    {
+        getyx(win, oy, ox);
+        put_str(optstr, win);
+        return get_ro(win, oy, ox);
+    }
+    else
+        return get_str(optstr, win);
+}
+
 /*
  * The ability field is read-only
  */
@@ -343,6 +359,11 @@
 	 * Look it up and deal with it
 	 */
 	for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
+            /* None of these can be changed if using system savefiles. */
+            if (use_savedir && (!strcmp(op->o_name, "name") ||
+                                !strcmp(op->o_name, "file") ||
+                                !strcmp(op->o_name, "score") ))
+                continue;
 	    if (EQSTR(str, op->o_name, len))
 	    {
 		if (op->o_putfunc == put_bool)	/* if option is a boolean */