diff src/luan/host/WebHandler.java @ 1330:f41919741100

fix security
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 11 Feb 2019 01:38:55 -0700
parents 307e76ccd0d6
children 11b7e11f9ed5
line wrap: on
line diff
--- 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");
-		}
-	};
 }