changeset 203:99eef1d0e706

IO security git-svn-id: https://luan-java.googlecode.com/svn/trunk@204 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Sun, 06 Jul 2014 03:54:08 +0000
parents 75750ceb45ee
children cee6581b6f56
files core/src/luan/impl/LuanParser.java core/src/luan/modules/IoLuan.java core/src/luan/modules/Utils.java dist/luan-core-trunk.jar dist/luan-web-trunk.jar web/src/luan/modules/web/LuanHandler.java
diffstat 6 files changed, 76 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/core/src/luan/impl/LuanParser.java	Fri Jul 04 17:18:39 2014 +0000
+++ b/core/src/luan/impl/LuanParser.java	Sun Jul 06 03:54:08 2014 +0000
@@ -834,9 +834,9 @@
 		List<TableExpr.Field> fields = new ArrayList<TableExpr.Field>();
 		List<Expressions> builder = new ArrayList<Expressions>();
 		while( Field(fields,builder,in) && FieldSep(inParens) );
-		Spaces(inParens);
 		if( !parser.match('}') )
 			throw parser.exception("Expected table element or '}'");
+		Spaces(in);
 		return parser.success( new TableExpr( se(start), fields.toArray(new TableExpr.Field[0]), ExpList.build(builder) ) );
 	}
 
--- a/core/src/luan/modules/IoLuan.java	Fri Jul 04 17:18:39 2014 +0000
+++ b/core/src/luan/modules/IoLuan.java	Sun Jul 06 03:54:08 2014 +0000
@@ -22,6 +22,8 @@
 import java.net.Socket;
 import java.net.ServerSocket;
 import java.net.MalformedURLException;
+import java.util.List;
+import java.util.ArrayList;
 import luan.LuanState;
 import luan.LuanTable;
 import luan.LuanFunction;
@@ -311,8 +313,8 @@
 	public static final class LuanUrl extends LuanIn {
 		private final URL url;
 
-		private LuanUrl(String s) throws MalformedURLException {
-			this.url = new URL(s);
+		private LuanUrl(URL url) throws LuanException {
+			this.url = url;
 		}
 
 		@Override InputStream inputStream() throws IOException {
@@ -327,8 +329,9 @@
 	public static final class LuanFile extends LuanIO {
 		private final File file;
 
-		private LuanFile(String name) {
-			this(new File(name));
+		private LuanFile(LuanState luan,File file) throws LuanException {
+			this(file);
+			check(luan,file.toString());
 		}
 
 		private LuanFile(File file) {
@@ -347,17 +350,17 @@
 			return file.toString();
 		}
 
-		public LuanTable child(String name) {
-			return new LuanFile(new File(file,name)).table();
+		public LuanTable child(LuanState luan,String name) throws LuanException {
+			return new LuanFile(luan,new File(file,name)).table();
 		}
 
-		public LuanTable children() {
+		public LuanTable children(LuanState luan) throws LuanException {
 			File[] files = file.listFiles();
 			if( files==null )
 				return null;
 			LuanTable list = new LuanTable();
 			for( File f : files ) {
-				list.add(new LuanFile(f).table());
+				list.add(new LuanFile(luan,f).table());
 			}
 			return list;
 		}
@@ -394,10 +397,10 @@
 					File.class.getMethod( "lastModified" ), file
 				) );
 				tbl.put( "child", new LuanJavaFunction(
-					LuanFile.class.getMethod( "child", String.class ), this
+					LuanFile.class.getMethod( "child", LuanState.class, String.class ), this
 				) );
 				tbl.put( "children", new LuanJavaFunction(
-					LuanFile.class.getMethod( "children" ), this
+					LuanFile.class.getMethod( "children", LuanState.class ), this
 				) );
 			} catch(NoSuchMethodException e) {
 				throw new RuntimeException(e);
@@ -407,15 +410,13 @@
 	}
 
 	public static LuanIn luanIo(LuanState luan,String name) throws LuanException {
-		if( Utils.isFile(name) )
-			return new LuanFile(name);
-		String url = Utils.toUrl(name);
+		check(luan,name);
+		File file = Utils.toFile(name);
+		if( file != null )
+			return new LuanFile(file);
+		URL url = Utils.toUrl(name);
 		if( url != null ) {
-			try {
-				return new LuanUrl(url);
-			} catch(MalformedURLException e) {
-				throw new RuntimeException(e);
-			}
+			return new LuanUrl(url);
 		}
 		throw luan.exception( "file '"+name+"' not found" );
 	}
@@ -498,5 +499,51 @@
 		};
 	}
 
+
+	// security
+
+	public interface Security {
+		public void check(LuanState luan,String name) throws LuanException;
+	}
+
+	private static String SECURITY_KEY = "Io.Security";
+
+	private static void check(LuanState luan,String name) throws LuanException {
+		@SuppressWarnings("unchecked")
+		List<Security> list = (List<Security>)luan.registry().get(SECURITY_KEY);
+		if( list==null )
+			return;
+		for( Security s : list ) {
+			s.check(luan,name);
+		}
+	}
+
+	public static void addSecurity(LuanState luan,Security s) {
+		@SuppressWarnings("unchecked")
+		List<Security> list = (List<Security>)luan.registry().get(SECURITY_KEY);
+		if( list==null ) {
+			list = new ArrayList<Security>();
+			luan.registry().put(SECURITY_KEY,list);
+		}
+		list.add(s);
+	}
+
+	public static class DirSecurity implements Security {
+		private final String[] dirs;
+
+		public DirSecurity(LuanState luan,String[] dirs) {
+			this.dirs = dirs;
+		}
+
+		@Override public void check(LuanState luan,String name) throws LuanException {
+			for( String dir : dirs ) {
+				if( name.startsWith(dir) )
+					return;
+			}
+			throw luan.exception("Security violation - '"+name+"' not in allowed directory");
+		}
+	}
+
+
 	private void IoLuan() {}  // never
 }
--- a/core/src/luan/modules/Utils.java	Fri Jul 04 17:18:39 2014 +0000
+++ b/core/src/luan/modules/Utils.java	Sun Jul 06 03:54:08 2014 +0000
@@ -60,11 +60,14 @@
 		}
 	}
 
-	public static boolean isFile(String path) {
-		return !path.contains("//") && exists(new File(path));
+	public static File toFile(String path) {
+		if( path.contains("//") )
+			return null;
+		File file = new File(path);
+		return exists(file) ? file : null;
 	}
 
-	public static String toUrl(String path) {
+	public static URL toUrl(String path) {
 		if( path.indexOf(':') == -1 )
 			return null;
 		if( path.startsWith("java:") ) {
@@ -72,16 +75,15 @@
 			if( path.contains("//") )
 				return null;
 			URL url = ClassLoader.getSystemResource(path);
-			return url==null ? null : url.toString();
+			return url==null ? null : url;
 		}
 		try {
-			new URL(path);
-			return path;
+			return new URL(path);
 		} catch(MalformedURLException e) {}
 		return null;
 	}
 
 	public static boolean exists(String path) {
-		return isFile(path) || toUrl(path)!=null;
+		return toFile(path)!=null || toUrl(path)!=null;
 	}
 }
Binary file dist/luan-core-trunk.jar has changed
Binary file dist/luan-web-trunk.jar has changed
--- a/web/src/luan/modules/web/LuanHandler.java	Fri Jul 04 17:18:39 2014 +0000
+++ b/web/src/luan/modules/web/LuanHandler.java	Sun Jul 06 03:54:08 2014 +0000
@@ -30,7 +30,7 @@
 			response.setStatus(HttpServletResponse.SC_OK);
 		} catch(LuanException e) {
 //e.printStackTrace();
-			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,e.getMessage());
+			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,e.getFullMessage());
 		}
 		baseRequest.setHandled(true);
 	}