Mercurial Hosting > luan
changeset 1330:f41919741100
fix security
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 11 Feb 2019 01:38:55 -0700 |
parents | 5a39b006acd1 |
children | 02fe660e7748 |
files | conv.txt src/luan/Luan.java src/luan/LuanClosure.java src/luan/LuanException.java src/luan/LuanJavaOk.java src/luan/LuanState.java src/luan/LuanTable.java src/luan/host/Backup.java src/luan/host/Init.luan src/luan/host/WebHandler.java src/luan/host/init.luan src/luan/impl/Closure.java src/luan/impl/LuanCompiler.java src/luan/impl/LuanImpl.java src/luan/impl/LuanParser.java src/luan/modules/BasicLuan.java src/luan/modules/Boot.luan src/luan/modules/Io.luan src/luan/modules/IoLuan.java src/luan/modules/JavaLuan.java src/luan/modules/PackageLuan.java src/luan/modules/TableLuan.java src/luan/modules/ThreadLuan.java src/luan/modules/lucene/Lucene.luan src/luan/modules/parsers/Css.java src/luan/modules/parsers/Csv.java src/luan/modules/parsers/Html.java |
diffstat | 27 files changed, 367 insertions(+), 322 deletions(-) [+] |
line wrap: on
line diff
--- a/conv.txt Sun Feb 10 02:01:49 2019 -0700 +++ b/conv.txt Mon Feb 11 01:38:55 2019 -0700 @@ -1,3 +1,5 @@ +file - java.* +Io.unrestricted Thread.global_callable Thread.global Logging.luanhost_logger
--- a/src/luan/Luan.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/Luan.java Mon Feb 11 01:38:55 2019 -0700 @@ -202,5 +202,34 @@ } */ + + + // security + + public interface Security { + public void check(LuanState luan,LuanClosure closure,String op,Object... args) throws LuanException; + } + + private static String SECURITY_KEY = "Luan.Security"; + + public static void checkSecurity(LuanState luan,String op,Object... args) throws LuanException { + check(luan,1,op,args); + } + + public static void checkCallerSecurity(LuanState luan,String op,Object... args) throws LuanException { + check(luan,2,op,args); + } + + private static void check(LuanState luan,int i,String op,Object... args) throws LuanException { + Security s = (Security)luan.registry().get(SECURITY_KEY); + if( s!=null ) + s.check(luan,luan.peek(),op,args); + } + + public static Security setSecurity(LuanState luan,Security s) { + return (Security)luan.registry().put(SECURITY_KEY,s); + } + + private Luan() {} // never }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/LuanClosure.java Mon Feb 11 01:38:55 2019 -0700 @@ -0,0 +1,62 @@ +package luan; + +import luan.impl.Pointer; + + +public abstract class LuanClosure extends LuanFunction implements LuanCloneable, Cloneable { + public Pointer[] upValues; + public boolean javaOk; + public final String sourceName; + private LuanCloner cloner; + + public LuanClosure(int nUpValues,boolean javaOk,String sourceName) throws LuanException { + this.upValues = new Pointer[nUpValues]; + this.javaOk = javaOk; + this.sourceName = sourceName; + } + + @Override public LuanClosure shallowClone() { + check(); + try { + return (LuanClosure)clone(); + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + + @Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) { + LuanClosure clone = (LuanClosure)dc; + switch( cloner.type ) { + case COMPLETE: + clone.upValues = (Pointer[])cloner.clone(upValues); + return; + case INCREMENTAL: + clone.cloner = cloner; + clone.upValues = upValues; + return; + } + } + + private void check() { + if( cloner != null ) { + upValues = (Pointer[])cloner.clone(upValues); + cloner = null; + } + } + + @Override public final Object call(LuanState luan,Object[] args) throws LuanException { + if( luan.isLocked ) + throw new RuntimeException("luan is locked"); + check(); + luan.push(this); + try { + return doCall(luan,args); + } catch(StackOverflowError e) { + throw new LuanException( "stack overflow" ); + } finally { + luan.pop(); + } + } + + public abstract Object doCall(LuanState luan,Object[] args) throws LuanException; +}
--- a/src/luan/LuanException.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/LuanException.java Mon Feb 11 01:38:55 2019 -0700 @@ -95,13 +95,13 @@ sb.append( "\nCaused by: " ).append( getJavaStackTraceString(cause) ); return sb.toString(); } - +/* public static String currentSource() { LuanException ex = new LuanException("currentSource"); List<StackTraceElement> st = ex.justLuan(ex.getStackTrace()); return st.isEmpty() ? null : st.get(0).getFileName(); } - +*/ @Override public void printStackTrace(PrintStream s) { s.print("Luan: "); s.println(luanStackTrace());
--- a/src/luan/LuanJavaOk.java Sun Feb 10 02:01:49 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -package luan; - - -public final class LuanJavaOk implements LuanCloneable { - public boolean ok = false; - public boolean unrestrictedIo = false; - - @Override public LuanJavaOk shallowClone() { - LuanJavaOk javaOk = new LuanJavaOk(); - javaOk.ok = ok; - javaOk.unrestrictedIo = unrestrictedIo; - return javaOk; - } - - @Override public void deepenClone(LuanCloneable clone,LuanCloner cloner) {} -}
--- a/src/luan/LuanState.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/LuanState.java Mon Feb 11 01:38:55 2019 -0700 @@ -20,7 +20,7 @@ public final class LuanState implements LuanCloneable { private static final Logger logger = LoggerFactory.getLogger(LuanState.class); - public LuanJavaOk javaOk; + private final List<LuanClosure> stack = new ArrayList<LuanClosure>(); private Map registry; public boolean isLocked = false; @@ -30,7 +30,6 @@ public OnClose onClose; public LuanState() { - javaOk = new LuanJavaOk(); registry = new HashMap(); } @@ -43,11 +42,27 @@ @Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) { LuanState clone = (LuanState)dc; clone.registry = cloner.clone(registry); - clone.javaOk = (LuanJavaOk)cloner.clone(javaOk); if( cloner.type == LuanCloner.Type.INCREMENTAL ) isLocked = true; } + public LuanClosure peek() { + return peek(1); + } + + public LuanClosure peek(int i) { + int n = stack.size(); + return n < i ? null : stack.get(n-i); + } + + void push(LuanClosure closure) { + stack.add(closure); + } + + void pop() { + stack.remove(stack.size()-1); + } + public Map registry() { return registry; } @@ -84,7 +99,7 @@ LuanTable tbl = (LuanTable)obj; return tbl.get(key); } - if( obj != null && javaOk.ok ) + if( obj != null && peek().javaOk ) return JavaLuan.__index(this,obj,key); throw new LuanException("attempt to index a " + Luan.type(obj) + " value" ); }
--- a/src/luan/LuanTable.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/LuanTable.java Mon Feb 11 01:38:55 2019 -0700 @@ -18,19 +18,20 @@ private Map map = null; private List list = null; private LuanTable metatable = null; - public LuanJavaOk javaOk; + public LuanClosure closure; private LuanCloner cloner; + private String security = null; public LuanTable(LuanState luan) { this.luan = luan; } - public LuanTable(LuanState luan,List list) { + public LuanTable(LuanState luan,List list){ int n = list.size(); for( int i=0; i<n; i++ ) { Object val = list.get(i); if( val != null ) - rawPut(i+1,val); + rawPut2(i+1,val); } } @@ -41,15 +42,15 @@ Object key = entry.getKey(); Object value = entry.getValue(); if( key != null && value != null ) - rawPut(key,value); + rawPut2(key,value); } } - public LuanTable(LuanState luan,Set set) { + public LuanTable(LuanState luan,Set set){ this.luan = luan; for( Object el : set ) { if( el != null ) - rawPut(el,Boolean.TRUE); + rawPut2(el,Boolean.TRUE); } } @@ -69,6 +70,7 @@ @Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) { check(); LuanTable clone = (LuanTable)dc; + clone.security = security; switch( cloner.type ) { case COMPLETE: deepenClone(clone,cloner); @@ -78,7 +80,7 @@ clone.map = map; clone.list = list; clone.metatable = metatable; - clone.javaOk = javaOk; + clone.closure = closure; return; } } @@ -108,7 +110,7 @@ clone.list = newList; } clone.metatable = (LuanTable)cloner.clone(metatable); - clone.javaOk = (LuanJavaOk)cloner.clone(javaOk); + clone.closure = (LuanClosure)cloner.clone(closure); } public boolean isList() { @@ -189,7 +191,13 @@ throw new LuanException("invalid type "+Luan.type(h)+" for metamethod __new_index"); } - public void rawPut(Object key,Object val) { + public void rawPut(Object key,Object val) throws LuanException { + if( security != null ) + Luan.checkSecurity(luan,"table",security,"put",key,val); + rawPut2(key,val); + } + + private void rawPut2(Object key,Object val) { check(); Integer iT = Luan.asInteger(key); if( iT != null ) { @@ -437,7 +445,9 @@ return metatable; } - public void setMetatable(LuanTable metatable) { + public void setMetatable(LuanTable metatable) throws LuanException { + if( security != null ) + Luan.checkSecurity(luan,"table",security,"set_metatable",metatable); check(); this.metatable = metatable; } @@ -516,4 +526,8 @@ LuanFunction fn = (LuanFunction)get(fnName); return fn.call(luan,args); } + + public static void setSecurity(LuanTable tbl,String security) { + tbl.security = security; + } }
--- a/src/luan/host/Backup.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/host/Backup.java Mon Feb 11 01:38:55 2019 -0700 @@ -127,7 +127,7 @@ public static void main(String[] args) throws Exception { Log4j.initForConsole(); - WebHandler.allowJavaFileName = args[2]; + WebHandler.securityPassword = args[2]; backup( new File(args[0]), new File(args[1]) ); System.exit(0); }
--- a/src/luan/host/Init.luan Sun Feb 10 02:01:49 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -local Luan = require "luan:Luan.luan" -local error = Luan.error -local do_file = Luan.do_file or error() -local String = require "luan:String.luan" -local gsub = String.gsub or error() - - -local Init = {} - -local dir, domain, logging = ... - - --- logging - -if logging then - java() - local LuanLogger = require "java:luan.modules.logging.LuanLogger" - local Level = require "java:org.apache.log4j.Level" - local EnhancedPatternLayout = require "java:org.apache.log4j.EnhancedPatternLayout" - local RollingFileAppender = require "java:org.apache.log4j.RollingFileAppender" - - local logger = LuanLogger.getRootLogger() - logger.removeAllAppenders() - local layout = EnhancedPatternLayout.new("%d %-5p %c - %m%n") - local log_dir = dir.."/site/private/local/logs/" - - local function add_appender(file,level) - local appender = RollingFileAppender.new(layout, log_dir..file) - appender.setMaxFileSize("1MB") - logger.addAppender(appender) - if level ~= logger.getEffectiveLevel() then - appender.setThreshold(level) - end - end - - add_appender("error.log",Level.ERROR) - add_appender("warn.log",Level.WARN) - add_appender("info.log",Level.INFO) -end - - - --- set vars - -local Io = require "luan:Io.luan" -local Http = require "luan:http/Http.luan" -local Hosting = require "luan:host/Hosting.luan" -local Mail = require "luan:mail/Mail.luan" - -Init.password = do_file(dir.."/info.luan").password or error() - -Http.dir = "file:"..dir.."/site" - -function Io.schemes.site(path,loading) - return Io.uri( Http.dir..path, loading ) -end - -Http.domain = domain -Io.password = Init.password - - --- mail - fix later - -Hosting.send_mail = Mail.Sender{ - host = "smtpcorp.com" - username = "smtp@luan.ws" -- ? - password = "luanhost" - port = 2525 -}.send - - --- callback to luanhost code -do_file "file:init.luan" - - -return Init
--- a/src/luan/host/WebHandler.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/host/WebHandler.java Mon Feb 11 01:38:55 2019 -0700 @@ -7,11 +7,13 @@ import luan.webserver.Request; import luan.webserver.Response; import luan.webserver.handlers.DomainHandler; +import luan.Luan; import luan.LuanState; import luan.LuanException; import luan.LuanTable; -import luan.modules.IoLuan; -import luan.modules.JavaLuan; +import luan.LuanFunction; +import luan.LuanClosure; +import luan.modules.BasicLuan; import luan.modules.http.LuanHandler; import luan.modules.logging.LuanLogger; @@ -19,6 +21,14 @@ public class WebHandler implements Handler { private static final Logger logger = LoggerFactory.getLogger(WebHandler.class); + private static final class LuanRuntimeException extends RuntimeException { + final LuanException e; + + LuanRuntimeException(LuanException e) { + this.e = e; + } + } + private static final DomainHandler.Factory factory = new DomainHandler.Factory() { public Handler newHandler(String domain) { File dir = new File(sitesDir,domain); @@ -40,7 +50,7 @@ } }; - public static String allowJavaFileName = "allow_java"; // change for security + public static String securityPassword = "password"; // change for security private static final DomainHandler domainHandler = new DomainHandler(factory); private static String sitesDir = null; @@ -90,59 +100,62 @@ return true; } */ - static LuanTable initLuan(LuanState luan,String dir,String domain,boolean logging) { - LuanTable init; + static void initLuan(LuanState luan,String dir,String domain,boolean logging) { + security(luan,dir); try { - init = (LuanTable)luan.eval( - "local Luan = require 'luan:Luan.luan'\n" - +"local f = Luan.load_file 'classpath:luan/host/Init.luan'\n" - +"return f('"+dir+"','"+domain+"',"+logging+")\n" - ); + LuanFunction fn = BasicLuan.load_file(luan,"classpath:luan/host/init.luan"); + fn.call(luan,new Object[]{dir,domain,logging}); } catch(LuanException e) { - throw new RuntimeException(e); + throw new LuanRuntimeException(e); } - File allowJavaFile = new File(dir,"site/private/"+allowJavaFileName); - if( !allowJavaFile.exists() ) { - JavaLuan.setSecurity( luan, javaSecurity ); - IoLuan.setSecurity( luan, ioSecurity(dir) ); - } - return init; } public static void removeHandler(String domain) { domainHandler.removeHandler(domain); } - public static void loadHandler(String domain) { - domainHandler.getHandler(domain); + public static void loadHandler(String domain) throws LuanException { + try { + domainHandler.getHandler(domain); + } catch(LuanRuntimeException e) { + throw e.e; + } } - private static final IoLuan.Security ioSecurity(String dir) { + private static final void security(LuanState luan,String dir) { final String siteUri = "file:" + dir + "/site"; - return new IoLuan.Security() { - public void check(LuanState luan,String name) throws LuanException { - if( name.startsWith("file:") ) { - if( name.contains("..") ) - throw new LuanException("Security violation - '"+name+"' contains '..'"); - if( !(name.equals(siteUri) || name.startsWith(siteUri+"/")) ) - throw new LuanException("Security violation - '"+name+"' outside of site dir"); - } - else if( name.startsWith("classpath:luan/host/") ) { - throw new LuanException("Security violation"); - } - else if( name.startsWith("os:") || name.startsWith("bash:") ) { - throw new LuanException("Security violation"); + Luan.Security security = new Luan.Security() { + public void check(LuanState luan,LuanClosure closure,String op,Object... args) + throws LuanException + { + if( op.equals("uri") ) { + String name = (String)args[0]; + if( name.startsWith("file:") ) { + if( name.contains("..") ) + throw new LuanException("Security violation - '"+name+"' contains '..'"); + if( !(name.equals(siteUri) || name.startsWith(siteUri+"/")) ) + throw new LuanException("Security violation - '"+name+"' outside of site dir"); + } + else if( name.startsWith("classpath:luan/host/") ) { + throw new LuanException("Security violation"); + } + else if( name.startsWith("os:") || name.startsWith("bash:") ) { + throw new LuanException("Security violation"); + } + } else { + String name = closure.sourceName; + if( !( + name.startsWith("luan:") + || name.startsWith("classpath:") + || name.matches("^file:[^/]+$") + ) ) + throw new LuanException("Security violation - only luan:* modules can load Java"); + if( name.equals("luan:logging/Logging") ) + throw new LuanException("Security violation - cannot reload Logging"); } } }; + Luan.setSecurity(luan,security); } - private static final JavaLuan.Security javaSecurity = new JavaLuan.Security() { - public void check(LuanState luan,String name) throws LuanException { - if( !(name.startsWith("luan:") || name.matches("^file:[^/]+$")) ) - throw new LuanException("Security violation - only luan:* modules can load Java"); - if( name.equals("luan:logging/Logging") ) - throw new LuanException("Security violation - cannot reload Logging"); - } - }; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/host/init.luan Mon Feb 11 01:38:55 2019 -0700 @@ -0,0 +1,81 @@ +local Luan = require "luan:Luan.luan" +local error = Luan.error +local do_file = Luan.do_file or error() +local String = require "luan:String.luan" +local gsub = String.gsub or error() + + +local dir, domain, logging = ... + + +-- logging + +if logging then + java() + local LuanLogger = require "java:luan.modules.logging.LuanLogger" + local Level = require "java:org.apache.log4j.Level" + local EnhancedPatternLayout = require "java:org.apache.log4j.EnhancedPatternLayout" + local RollingFileAppender = require "java:org.apache.log4j.RollingFileAppender" + + local logger = LuanLogger.getRootLogger() + logger.removeAllAppenders() + local layout = EnhancedPatternLayout.new("%d %-5p %c - %m%n") + local log_dir = dir.."/site/private/local/logs/" + + local function add_appender(file,level) + local appender = RollingFileAppender.new(layout, log_dir..file) + appender.setMaxFileSize("1MB") + logger.addAppender(appender) + if level ~= logger.getEffectiveLevel() then + appender.setThreshold(level) + end + end + + add_appender("error.log",Level.ERROR) + add_appender("warn.log",Level.WARN) + add_appender("info.log",Level.INFO) +end + + + +-- set vars + +local Io = require "luan:Io.luan" +local Http = require "luan:http/Http.luan" +local Hosting = require "luan:host/Hosting.luan" +local Mail = require "luan:mail/Mail.luan" + +Io.password = do_file(dir.."/info.luan").password or error() + +Http.dir = "file:"..dir.."/site" + +function Io.schemes.site(path,loading) + return Io.uri( Http.dir..path, loading ) +end + +Http.domain = domain + + +-- mail - fix later + +Hosting.send_mail = Mail.Sender{ + host = "smtpcorp.com" + username = "smtp@luan.ws" -- ? + password = "luanhost" + port = 2525 +}.send + + +-- callback to luanhost code +do_file "file:init.luan" + + + +java() +local WebHandler = require "java:luan.host.WebHandler" +local LuanJava = require "java:luan.Luan" + +function Hosting.no_security(password) + WebHandler.securityPassword == password or error "wrong password" + LuanJava.setSecurity(nil) +end
--- a/src/luan/impl/Closure.java Sun Feb 10 02:01:49 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -package luan.impl; - -import luan.Luan; -import luan.LuanFunction; -import luan.LuanState; -import luan.LuanException; -import luan.LuanCloner; -import luan.LuanCloneable; -import luan.LuanJavaOk; - - -public abstract class Closure extends LuanFunction implements LuanCloneable, Cloneable { - protected Pointer[] upValues; - protected LuanJavaOk javaOk; - private LuanCloner cloner; - - public Closure(int nUpValues,LuanJavaOk javaOk) throws LuanException { - this.upValues = new Pointer[nUpValues]; - this.javaOk = javaOk; - } - - @Override public Closure shallowClone() { - check(); - try { - return (Closure)clone(); - } catch(CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } - - @Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) { - Closure clone = (Closure)dc; - switch( cloner.type ) { - case COMPLETE: - clone.upValues = (Pointer[])cloner.clone(upValues); - clone.javaOk = (LuanJavaOk)cloner.clone(javaOk); - return; - case INCREMENTAL: - clone.cloner = cloner; - clone.upValues = upValues; - clone.javaOk = javaOk; - return; - } - } - - private void check() { - if( cloner != null ) { - upValues = (Pointer[])cloner.clone(upValues); - javaOk = (LuanJavaOk)cloner.clone(javaOk); - cloner = null; - } - } - - @Override public final Object call(LuanState luan,Object[] args) throws LuanException { - if( luan.isLocked ) - throw new RuntimeException("luan is locked"); - check(); - LuanJavaOk old = luan.javaOk; - luan.javaOk = javaOk; - try { - return doCall(luan,args); - } catch(StackOverflowError e) { - throw new LuanException( "stack overflow" ); - } finally { - luan.javaOk = old; - } - } - - public abstract Object doCall(LuanState luan,Object[] args) throws LuanException; -}
--- a/src/luan/impl/LuanCompiler.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/impl/LuanCompiler.java Mon Feb 11 01:38:55 2019 -0700 @@ -8,7 +8,7 @@ import luan.LuanState; import luan.LuanException; import luan.LuanTable; -import luan.LuanJavaOk; +import luan.LuanClosure; import luan.modules.JavaLuan; import luan.modules.PackageLuan; @@ -18,19 +18,12 @@ public static LuanFunction compile(String sourceText,String sourceName,LuanTable env) throws LuanException { Class fnClass = env==null ? getClass(sourceText,sourceName) : getClass(sourceText,sourceName,env); - LuanJavaOk javaOk; - if( env == null ) { - javaOk = new LuanJavaOk(); - } else { - javaOk = env.javaOk; - if( javaOk == null ) { - javaOk = new LuanJavaOk(); - env.javaOk = javaOk; - } - } - Closure closure; + boolean javaOk = false; + if( env != null && env.closure != null ) + javaOk = env.closure.javaOk; + LuanClosure closure; try { - closure = (Closure)fnClass.getConstructor(LuanJavaOk.class).newInstance(javaOk); + closure = (LuanClosure)fnClass.getConstructor(Boolean.TYPE,String.class).newInstance(javaOk,sourceName); } catch(NoSuchMethodException e) { throw new RuntimeException(e); } catch(InstantiationException e) { @@ -42,7 +35,10 @@ } closure.upValues[0].o = JavaLuan.javaFn; closure.upValues[1].o = PackageLuan.requireFn; - if( env != null ) closure.upValues[2].o = env; + if( env != null ) { + closure.upValues[2].o = env; + env.closure = closure; + } return closure; }
--- a/src/luan/impl/LuanImpl.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/impl/LuanImpl.java Mon Feb 11 01:38:55 2019 -0700 @@ -162,7 +162,7 @@ tbl.put(key,value); return; } - if( t != null && luan.javaOk.ok ) + if( t != null && luan.peek().javaOk ) JavaLuan.__new_index(luan,t,key,value); else throw new LuanException( "attempt to index a " + Luan.type(t) + " value" ); @@ -229,7 +229,7 @@ } } - public static LuanTable table(LuanState luan,Object[] a) { + public static LuanTable table(LuanState luan,Object[] a) throws LuanException { LuanTable table = new LuanTable(luan); int i = 0; for( Object fld : a ) {
--- a/src/luan/impl/LuanParser.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/impl/LuanParser.java Mon Feb 11 01:38:55 2019 -0700 @@ -2009,16 +2009,16 @@ stmts.add( "\nreturn LuanFunction.NOTHING;" ); return "" +"package luan.impl; " + +"import luan.LuanClosure; " +"import luan.Luan; " +"import luan.LuanFunction; " +"import luan.LuanState; " - +"import luan.LuanJavaOk; " +"import luan.LuanException; " +"import luan.modules.PackageLuan; " - +"public class " + className +" extends Closure { " - +"public "+className+"(LuanJavaOk java) throws LuanException { " - +"super("+upValueSymbols.size()+",java); " + +"public class " + className +" extends LuanClosure { " + +"public "+className+"(boolean javaOk,String sourceName) throws LuanException { " + +"super("+upValueSymbols.size()+",javaOk,sourceName); " + init(upValueSymbols) +"} " @@ -2038,7 +2038,7 @@ stmt.add( "return LuanFunction.NOTHING; " ); Expr exp = new Expr(Val.SINGLE,false); exp.add( "" - +"new Closure("+upValueSymbols.size()+",javaOk) { " + +"new LuanClosure("+upValueSymbols.size()+",javaOk,sourceName) { " +"{ " + init(upValueSymbols) +"} "
--- a/src/luan/modules/BasicLuan.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/modules/BasicLuan.java Mon Feb 11 01:38:55 2019 -0700 @@ -88,7 +88,7 @@ return table.rawGet(index); } - public static void raw_set(LuanTable table,Object index,Object value) { + public static void raw_set(LuanTable table,Object index,Object value) throws LuanException { table.rawPut(index,value); } @@ -240,4 +240,5 @@ return LuanToString.toString(obj,b); } + private void BasicLuan() {} // never }
--- a/src/luan/modules/Boot.luan Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/modules/Boot.luan Mon Feb 11 01:38:55 2019 -0700 @@ -5,11 +5,13 @@ local new_error = BasicLuan.new_error local ipairs = BasicLuan.ipairs local set_metatable = BasicLuan.set_metatable +local try = BasicLuan.try_ local StringLuan = require "java:luan.modules.StringLuan" local match = StringLuan.match -- String.match local IoLuan = require "java:luan.modules.IoLuan" local LuanUrl = require "java:luan.modules.url.LuanUrl" -IoLuan.unrestricted() -- not right +local LuanJava = require "java:luan.Luan" +local LuanTable = require "java:luan.LuanTable" local Boot = {} @@ -20,6 +22,20 @@ end Boot.error = error +local function no_security(fn) + LuanJava.checkCallerSecurity("no_security") + return function(...) + local security = LuanJava.setSecurity(nil) + return try( { + fn + finally = function() + security and LuanJava.setSecurity(security) + end + }, ... ) + end +end +Boot.no_security = no_security + local function new_LuanIn(io) local this = {} @@ -69,6 +85,7 @@ end local schemes = {} +LuanTable.setSecurity(schemes,"schemes") function schemes.null(path) return new_LuanIO( IoLuan.nullIO )
--- a/src/luan/modules/Io.luan Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/modules/Io.luan Mon Feb 11 01:38:55 2019 -0700 @@ -14,7 +14,6 @@ Io.stdin = Boot.new_LuanIn( IoLuan.defaultStdin ) Io.stdout = Boot.text_writer(System.out) Io.stderr = Boot.text_writer(System.err) -Io.unrestricted = IoLuan.unrestricted -- used by http and rpc Io.password = "password"
--- a/src/luan/modules/IoLuan.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/modules/IoLuan.java Mon Feb 11 01:38:55 2019 -0700 @@ -28,6 +28,7 @@ import java.nio.file.Files; import java.util.Enumeration; import java.util.Map; +import luan.Luan; import luan.LuanState; import luan.LuanTable; import luan.LuanFunction; @@ -640,44 +641,24 @@ } } - public static LuanTable my_ips(LuanState luan) throws IOException { + public static LuanTable my_ips(LuanState luan) throws IOException, LuanException { LuanTable tbl = new LuanTable(luan); for( Enumeration<NetworkInterface> e1 = NetworkInterface.getNetworkInterfaces(); e1.hasMoreElements(); ) { NetworkInterface ni = e1.nextElement(); for( Enumeration<InetAddress> e2 = ni.getInetAddresses(); e2.hasMoreElements(); ) { InetAddress ia = e2.nextElement(); if( ia instanceof Inet4Address ) - tbl.rawPut(ia.getHostAddress(),true); + tbl.put(ia.getHostAddress(),true); } } return tbl; } - // security - - public static void unrestricted(LuanState luan) throws LuanException { - JavaLuan.check(luan); - luan.javaOk.unrestrictedIo = true; - } - - public interface Security { - public void check(LuanState luan,String name) throws LuanException; + private static void check(LuanState luan,String name) throws LuanException { + Luan.checkSecurity(luan,"uri",name); } - private static String SECURITY_KEY = "Io.Security"; - - private static void check(LuanState luan,String name) throws LuanException { - if( luan.javaOk.unrestrictedIo ) - return; - Security s = (Security)luan.registry().get(SECURITY_KEY); - if( s!=null ) - s.check(luan,name); - } - - public static void setSecurity(LuanState luan,Security s) { - luan.registry().put(SECURITY_KEY,s); - } private void IoLuan() {} // never }
--- a/src/luan/modules/JavaLuan.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/modules/JavaLuan.java Mon Feb 11 01:38:55 2019 -0700 @@ -28,8 +28,8 @@ public final class JavaLuan { public static void java(LuanState luan) throws LuanException { - check(luan); - luan.javaOk.ok = true; + Luan.checkSecurity(luan,"java"); + luan.peek().javaOk = true; } public static final LuanFunction javaFn; @@ -42,7 +42,7 @@ } private static void checkJava(LuanState luan) throws LuanException { - if( !luan.javaOk.ok ) + if( !luan.peek().javaOk ) throw new LuanException("Java isn't allowed"); } @@ -472,26 +472,5 @@ } */ - - - // security - - public interface Security { - public void check(LuanState luan,String name) throws LuanException; - } - - private static String SECURITY_KEY = "Java.Security"; - - static void check(LuanState luan) throws LuanException { - Security s = (Security)luan.registry().get(SECURITY_KEY); - if( s!=null ) { - String name = LuanException.currentSource(); - s.check(luan,name); - } - } - - public static void setSecurity(LuanState luan,Security s) { - luan.registry().put(SECURITY_KEY,s); - } - + private void JavaLuan() {} // never }
--- a/src/luan/modules/PackageLuan.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/modules/PackageLuan.java Mon Feb 11 01:38:55 2019 -0700 @@ -93,10 +93,14 @@ } catch(LuanException e) { throw new RuntimeException(e); } + Luan.Security security = Luan.setSecurity(luan,null); try { return (String)Luan.first(boot.call("read",uri)); } catch(LuanException e) { return null; + } finally { + if( security != null ) + Luan.setSecurity(luan,security); } }
--- a/src/luan/modules/TableLuan.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/modules/TableLuan.java Mon Feb 11 01:38:55 2019 -0700 @@ -84,7 +84,7 @@ } } - public static LuanTable pack(LuanState luan,Object... args) { + public static LuanTable pack(LuanState luan,Object... args) throws LuanException { LuanTable tbl = new LuanTable(luan,Arrays.asList(args)); tbl.rawPut( "n", args.length ); return tbl;
--- a/src/luan/modules/ThreadLuan.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/modules/ThreadLuan.java Mon Feb 11 01:38:55 2019 -0700 @@ -130,7 +130,7 @@ } } - private static Object makeSafe(LuanState luan,Object v) { + private static Object makeSafe(LuanState luan,Object v) throws LuanException { if( v instanceof LuanTable ) { LuanTable tbl = (LuanTable)v; if( tbl.getMetatable() != null )
--- a/src/luan/modules/lucene/Lucene.luan Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/modules/lucene/Lucene.luan Mon Feb 11 01:38:55 2019 -0700 @@ -6,7 +6,6 @@ local set_metatable = Luan.set_metatable or error() local Html = require "luan:Html.luan" local Io = require "luan:Io.luan" -Io.unrestricted() local uri = Io.uri or error() local String = require "luan:String.luan" local matches = String.matches or error()
--- a/src/luan/modules/parsers/Css.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/modules/parsers/Css.java Mon Feb 11 01:38:55 2019 -0700 @@ -2,13 +2,18 @@ import luan.LuanState; import luan.LuanTable; +import luan.LuanException; import luan.lib.parser.Parser; public final class Css { public static LuanTable style(LuanState luan,String text) { - return new Css(luan,text).parseStyle(); + try { + return new Css(luan,text).parseStyle(); + } catch(LuanException e) { + throw new RuntimeException(e); + } } private final LuanState luan; @@ -19,7 +24,7 @@ this.parser = new Parser(text); } - private LuanTable parseStyle() { + private LuanTable parseStyle() throws LuanException { LuanTable tbl = new LuanTable(luan); while( matchSpace() ); while( !parser.endOfInput() ) { @@ -37,7 +42,7 @@ while( !parser.endOfInput() && parser.noneOf(";") ); String val = parser.textFrom(start).trim(); - tbl.rawPut(prop,val); + tbl.put(prop,val); parser.match(';'); while( matchSpace() ); }
--- a/src/luan/modules/parsers/Csv.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/modules/parsers/Csv.java Mon Feb 11 01:38:55 2019 -0700 @@ -2,6 +2,7 @@ import luan.LuanState; import luan.LuanTable; +import luan.LuanException; import luan.lib.parser.Parser; import luan.lib.parser.ParseException; @@ -9,7 +10,11 @@ public final class Csv { public static LuanTable toList(LuanState luan,String line) throws ParseException { - return new Csv(line).parse(luan); + try { + return new Csv(line).parse(luan); + } catch(LuanException e) { + throw new RuntimeException(e); + } } private final Parser parser; @@ -22,12 +27,12 @@ return new ParseException(parser,msg); } - private LuanTable parse(LuanState luan) throws ParseException { + private LuanTable parse(LuanState luan) throws ParseException, LuanException { LuanTable list = new LuanTable(luan); while(true) { Spaces(); String field = parseField(); - list.rawPut(list.rawLength()+1,field); + list.put(list.rawLength()+1,field); Spaces(); if( parser.endOfInput() ) return list;
--- a/src/luan/modules/parsers/Html.java Sun Feb 10 02:01:49 2019 -0700 +++ b/src/luan/modules/parsers/Html.java Mon Feb 11 01:38:55 2019 -0700 @@ -6,13 +6,18 @@ import java.util.HashSet; import luan.LuanState; import luan.LuanTable; +import luan.LuanException; import luan.lib.parser.Parser; public final class Html { public static LuanTable toList(LuanState luan,String text,LuanTable containerTagsTbl) { - return new Html(luan,text,containerTagsTbl).parse(); + try { + return new Html(luan,text,containerTagsTbl).parse(); + } catch(LuanException e) { + throw new RuntimeException(e); + } } private final LuanState luan; @@ -27,7 +32,7 @@ } } - private LuanTable parse() { + private LuanTable parse() throws LuanException { List list = new ArrayList(); StringBuilder sb = new StringBuilder(); while( !parser.endOfInput() ) { @@ -61,7 +66,7 @@ return new LuanTable(luan,list); } - private LuanTable parseComment() { + private LuanTable parseComment() throws LuanException { parser.begin(); if( !parser.match("<!--") ) return parser.failure(null); @@ -72,12 +77,12 @@ } String text = parser.textFrom(start); LuanTable tbl = new LuanTable(luan); - tbl.rawPut("type","comment"); - tbl.rawPut("text",text); + tbl.put("type","comment"); + tbl.put("text",text); return parser.success(tbl); } - private LuanTable parseCdata() { + private LuanTable parseCdata() throws LuanException { parser.begin(); if( !parser.match("<![CDATA[") ) return parser.failure(null); @@ -88,12 +93,12 @@ } String text = parser.textFrom(start); LuanTable tbl = new LuanTable(luan); - tbl.rawPut("type","cdata"); - tbl.rawPut("text",text); + tbl.put("type","cdata"); + tbl.put("text",text); return parser.success(tbl); } - private LuanTable parseContainer(LuanTable tag) { + private LuanTable parseContainer(LuanTable tag) throws LuanException { String endTagName = '/' + (String)tag.rawGet("name"); int start = parser.begin(); int end; @@ -110,15 +115,15 @@ } String text = parser.text.substring(start,end); LuanTable tbl = new LuanTable(luan); - tbl.rawPut("type","container"); - tbl.rawPut("tag",tag); - tbl.rawPut("text",text); + tbl.put("type","container"); + tbl.put("tag",tag); + tbl.put("text",text); return parser.success(tbl); } - private LuanTable parseTag() { + private LuanTable parseTag() throws LuanException { LuanTable tbl = new LuanTable(luan); - tbl.rawPut("type","tag"); + tbl.put("type","tag"); int tagStart = parser.begin(); if( !parser.match('<') ) return parser.failure(null); @@ -128,26 +133,26 @@ return parser.failure(null); while( matchNameChar() ); String name = parser.textFrom(start).toLowerCase(); - tbl.rawPut("name",name); + tbl.put("name",name); LuanTable attributes = new LuanTable(luan); - tbl.rawPut("attributes",attributes); + tbl.put("attributes",attributes); String attrName; while( (attrName = parseAttrName()) != null ) { String attrValue = parseAttrValue(); - attributes.rawPut( attrName, attrValue!=null ? attrValue : true ); + attributes.put( attrName, attrValue!=null ? attrValue : true ); if( attrName.equals("style") && attrValue!=null ) { LuanTable style = Css.style(luan,attrValue); if( style!=null ) - tbl.rawPut("style",style); + tbl.put("style",style); } } while( matchSpace() ); boolean isEmpty = parser.match('/'); - tbl.rawPut("is_empty",isEmpty); + tbl.put("is_empty",isEmpty); if( !parser.match('>') ) return parser.failure(null); String raw = parser.textFrom(tagStart); - tbl.rawPut("raw",raw); + tbl.put("raw",raw); return parser.success(tbl); }