1
0
Fork 0

- move fixpath() from "string" to "io" module

- first stab at Nasal security model: allow writing files only to authorized
  dirs. (Most of the debug messages will be removed later.)
This commit is contained in:
mfranz 2008-06-13 11:35:55 +00:00
parent 219f8d9a3a
commit 7d9bd68742
2 changed files with 66 additions and 31 deletions

View file

@ -113,4 +113,70 @@ var writexml = func(path, node, indent = "\t", prefix = "___") {
die("writexml(): tree has more than one root node");
}
# Removes superfluous slashes, empty and "." elements, expands
# all ".." elements, and turns all backslashes into slashes.
# The result will start with a slash if it started with a slash
# or backslash, it will end without slash. Should be applied on
# absolute property or file paths, otherwise ".." elements might
# be resolved wrongly.
#
var fixpath = func(path) {
var d = "";
for(var i = 0; i < size(path); i += 1)
d ~= path[i] == `\\` ? "/" : chr(path[i]);
var prefix = d[0] == `/` ? "/" : "";
var stack = [];
foreach(var e; split("/", d)) {
if(e == "." or e == "")
continue;
elsif(e == "..")
pop(stack);
else
append(stack, e);
}
if(!size(stack))
return "/";
path = stack[0];
foreach(var s; subvec(stack, 1))
path ~= "/" ~ s;
return prefix ~ path;
}
# Redefine io.open() such that files can only be written under authorized directories.
#
setlistener("/sim/signals/nasal-dir-initialized", func {
var writable_dirs = [
# "*", # any
# fixpath(getprop("/sim/fg-root")) ~ "/Scenery/",
fixpath(getprop("/sim/fg-home")) ~ "/",
"/tmp/", "/var/tmp/", "/var/log/",
"[A-Za-z]:TMP/", "[A-Za-z]:TEMP/",
"[A-Za-z]:/TMP/", "[A-Za-z]:/TEMP/",
];
var _open = open;
open = func(path, mode = "rb") {
var c = caller(1);
print(debug._path("SECURITY: io.open(\"" ~ path ~ "\", \"" ~ mode ~ "\")\n in file "
~ c[2] ~ ", line " ~ c[3]));
if(mode == "r") {
print(debug._nil("SECURITY: allow reading of file '" ~ path ~ "'"));
return _open(path, mode);
}
var fpath = fixpath(path);
if(fpath != path) print(debug._error("SECURITY: fix path '" ~ path ~ "' -> '" ~ fpath ~ "'"));
foreach(var p; writable_dirs) {
print("SECURITY: check for path '" ~ p ~ "'");
if(string.match(fpath, p ~ '*')) {
print(debug._nil("SECURITY: allow path '" ~ p ~ "'"));
return _open(fpath, mode);
}
}
die("io.open(): security: writing to file '" ~ path ~ "' denied\n ");
}
});

View file

@ -155,34 +155,3 @@ var match = func(str, patt) {
}
##
# Removes superfluous slashes, empty and "." elements, expands
# all ".." elements, and turns all backslashes into slashes.
# The result will start with a slash if it started with a slash
# or backslash, it will end without slash. Should be applied on
# absolute property or file paths, otherwise ".." elements might
# be resolved wrongly.
#
var fixpath = func(path) {
var d = "";
for (var i = 0; i < size(path); i += 1)
d ~= path[i] == `\\` ? "/" : chr(path[i]);
var prefix = d[0] == `/` ? "/" : "";
var stack = [];
foreach (var e; split("/", d)) {
if (e == "." or e == "")
continue;
elsif (e == "..")
pop(stack);
else
append(stack, e);
}
if (!size(stack))
return "/";
path = stack[0];
foreach (var s; subvec(stack, 1))
path ~= "/" ~ s;
return prefix ~ path;
}