read rules for io.open() file access from $FG_ROOT/Nasal/IOrules or, if
available, from $FG_HOME/Nasal/IOrules. That's desirable because ordinary users aren't allowed to edit files in $FG_ROOT.
This commit is contained in:
parent
7cc783c2f5
commit
bf9c2dc6a5
2 changed files with 73 additions and 8 deletions
31
Nasal/IOrules
Normal file
31
Nasal/IOrules
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Permissions for Nasal's io.open()
|
||||
#
|
||||
# This file defines which file paths can be opened for reading and/or
|
||||
# writing using Nasal's io.open() command. The respective code can be
|
||||
# found in $FG_ROOT/Nasal/io.nas.
|
||||
#
|
||||
# Empty lines and lines starting with '#' are ignored. All other entries
|
||||
# must be of the form
|
||||
#
|
||||
# {READ|WRITE} {ALLOW|DENY} <path-pattern>
|
||||
#
|
||||
# whereby fields must be separated by exactly one space. The pattern must
|
||||
# not be quoted and may contain spaces. If a pattern starts with $FG_ROOT/
|
||||
# or $FG_HOME/, then these parts are replaced by the respective system
|
||||
# paths. See $FG_ROOT/Nasal/string.nas for the pattern syntax.
|
||||
#
|
||||
# Entries are considered from top down. If no entry matches, then file
|
||||
# access is denied. A local rules file $FG_HOME/Nasal/IOrules using the
|
||||
# same syntax takes precedence over this file. The default rules that
|
||||
# apply when there's no Nasal/IOrules file at all are equivalent to this:
|
||||
#
|
||||
# READ DENY *
|
||||
# WRITE DENY *
|
||||
#
|
||||
# Read and write access to Nasal/IOrules files, however, is *always*
|
||||
# prohibited and not configurable!
|
||||
|
||||
READ ALLOW $FG_ROOT/*
|
||||
READ ALLOW $FG_HOME/*
|
||||
|
||||
WRITE ALLOW $FG_HOME/Export/*
|
50
Nasal/io.nas
50
Nasal/io.nas
|
@ -148,16 +148,50 @@ _setlistener("/sim/signals/nasal-dir-initialized", func {
|
|||
var _open = open;
|
||||
var root = string.fixpath(getprop("/sim/fg-root"));
|
||||
var home = string.fixpath(getprop("/sim/fg-home"));
|
||||
var config = "Nasal/IOrules";
|
||||
|
||||
var read_rules = [ # [pattern, allow(1)/deny(0)]
|
||||
[root ~ "/*", 1],
|
||||
[home ~ "/*", 1],
|
||||
];
|
||||
var read_rules = [];
|
||||
var write_rules = [];
|
||||
|
||||
var write_rules = [
|
||||
[home ~ "/Scenery/*.stg", 1],
|
||||
[home ~ "/Export/*", 1],
|
||||
];
|
||||
var load_rules = func(path) {
|
||||
if(stat(path) == nil)
|
||||
return 0;
|
||||
printlog("info", "using io.open() rules from ", path);
|
||||
read_rules = [];
|
||||
write_rules = [];
|
||||
var file = open(path, "r");
|
||||
var no = 0;
|
||||
while ((var line = readln(file)) != nil) {
|
||||
no += 1;
|
||||
if(!size(line) or line[0] == `#`)
|
||||
continue;
|
||||
|
||||
var f = split(" ", line);
|
||||
if(size(f) < 3 or (f[0] != "READ" and f[0] != "WRITE") and (f[1] != "DENY" and f[1] != "ALLOW")) {
|
||||
printlog("alert", "ERROR: invalid io.open() rule in ", path, ", line ", no, ": ", line);
|
||||
read_rules = write_rules = [];
|
||||
break; # don't use die() or return, as io.open() has yet to be redefined
|
||||
}
|
||||
var pattern = f[2];
|
||||
foreach (var p; subvec(f, 3))
|
||||
pattern ~= " " ~ p;
|
||||
if (substr(pattern, 0, 9) == "$FG_ROOT/")
|
||||
pattern = root ~ "/" ~ substr(pattern, 9);
|
||||
elsif (substr(pattern, 0, 9) == "$FG_HOME/")
|
||||
pattern = home ~ "/" ~ substr(pattern, 9);
|
||||
append(f[0] == "READ" ? read_rules : write_rules, [pattern, f[1] == "ALLOW"]);
|
||||
}
|
||||
close(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
load_rules(home ~ "/" ~ config) or load_rules(root ~ "/" ~ config);
|
||||
read_rules = [["*/" ~ config, 0]] ~ read_rules;
|
||||
write_rules = [["*/" ~ config, 0]] ~ write_rules;
|
||||
if(getprop("/sim/logging/priority") == "info") {
|
||||
print("READ: ", debug.string(read_rules));
|
||||
print("WRITE: ", debug.string(write_rules));
|
||||
}
|
||||
|
||||
open = func(path, mode = "rb") {
|
||||
var rules = write_rules;
|
||||
|
|
Loading…
Add table
Reference in a new issue