comparison core/src/luan/modules/IoLuan.java @ 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
comparison
equal deleted inserted replaced
202:75750ceb45ee 203:99eef1d0e706
20 import java.io.IOException; 20 import java.io.IOException;
21 import java.net.URL; 21 import java.net.URL;
22 import java.net.Socket; 22 import java.net.Socket;
23 import java.net.ServerSocket; 23 import java.net.ServerSocket;
24 import java.net.MalformedURLException; 24 import java.net.MalformedURLException;
25 import java.util.List;
26 import java.util.ArrayList;
25 import luan.LuanState; 27 import luan.LuanState;
26 import luan.LuanTable; 28 import luan.LuanTable;
27 import luan.LuanFunction; 29 import luan.LuanFunction;
28 import luan.LuanJavaFunction; 30 import luan.LuanJavaFunction;
29 import luan.LuanException; 31 import luan.LuanException;
309 } 311 }
310 312
311 public static final class LuanUrl extends LuanIn { 313 public static final class LuanUrl extends LuanIn {
312 private final URL url; 314 private final URL url;
313 315
314 private LuanUrl(String s) throws MalformedURLException { 316 private LuanUrl(URL url) throws LuanException {
315 this.url = new URL(s); 317 this.url = url;
316 } 318 }
317 319
318 @Override InputStream inputStream() throws IOException { 320 @Override InputStream inputStream() throws IOException {
319 return url.openStream(); 321 return url.openStream();
320 } 322 }
325 } 327 }
326 328
327 public static final class LuanFile extends LuanIO { 329 public static final class LuanFile extends LuanIO {
328 private final File file; 330 private final File file;
329 331
330 private LuanFile(String name) { 332 private LuanFile(LuanState luan,File file) throws LuanException {
331 this(new File(name)); 333 this(file);
334 check(luan,file.toString());
332 } 335 }
333 336
334 private LuanFile(File file) { 337 private LuanFile(File file) {
335 this.file = file; 338 this.file = file;
336 } 339 }
345 348
346 @Override public String to_string() { 349 @Override public String to_string() {
347 return file.toString(); 350 return file.toString();
348 } 351 }
349 352
350 public LuanTable child(String name) { 353 public LuanTable child(LuanState luan,String name) throws LuanException {
351 return new LuanFile(new File(file,name)).table(); 354 return new LuanFile(luan,new File(file,name)).table();
352 } 355 }
353 356
354 public LuanTable children() { 357 public LuanTable children(LuanState luan) throws LuanException {
355 File[] files = file.listFiles(); 358 File[] files = file.listFiles();
356 if( files==null ) 359 if( files==null )
357 return null; 360 return null;
358 LuanTable list = new LuanTable(); 361 LuanTable list = new LuanTable();
359 for( File f : files ) { 362 for( File f : files ) {
360 list.add(new LuanFile(f).table()); 363 list.add(new LuanFile(luan,f).table());
361 } 364 }
362 return list; 365 return list;
363 } 366 }
364 367
365 public boolean exists() { 368 public boolean exists() {
392 ) ); 395 ) );
393 tbl.put( "last_modified", new LuanJavaFunction( 396 tbl.put( "last_modified", new LuanJavaFunction(
394 File.class.getMethod( "lastModified" ), file 397 File.class.getMethod( "lastModified" ), file
395 ) ); 398 ) );
396 tbl.put( "child", new LuanJavaFunction( 399 tbl.put( "child", new LuanJavaFunction(
397 LuanFile.class.getMethod( "child", String.class ), this 400 LuanFile.class.getMethod( "child", LuanState.class, String.class ), this
398 ) ); 401 ) );
399 tbl.put( "children", new LuanJavaFunction( 402 tbl.put( "children", new LuanJavaFunction(
400 LuanFile.class.getMethod( "children" ), this 403 LuanFile.class.getMethod( "children", LuanState.class ), this
401 ) ); 404 ) );
402 } catch(NoSuchMethodException e) { 405 } catch(NoSuchMethodException e) {
403 throw new RuntimeException(e); 406 throw new RuntimeException(e);
404 } 407 }
405 return tbl; 408 return tbl;
406 } 409 }
407 } 410 }
408 411
409 public static LuanIn luanIo(LuanState luan,String name) throws LuanException { 412 public static LuanIn luanIo(LuanState luan,String name) throws LuanException {
410 if( Utils.isFile(name) ) 413 check(luan,name);
411 return new LuanFile(name); 414 File file = Utils.toFile(name);
412 String url = Utils.toUrl(name); 415 if( file != null )
416 return new LuanFile(file);
417 URL url = Utils.toUrl(name);
413 if( url != null ) { 418 if( url != null ) {
414 try { 419 return new LuanUrl(url);
415 return new LuanUrl(url);
416 } catch(MalformedURLException e) {
417 throw new RuntimeException(e);
418 }
419 } 420 }
420 throw luan.exception( "file '"+name+"' not found" ); 421 throw luan.exception( "file '"+name+"' not found" );
421 } 422 }
422 423
423 public static LuanTable File(LuanState luan,String name) throws LuanException { 424 public static LuanTable File(LuanState luan,String name) throws LuanException {
496 } 497 }
497 } 498 }
498 }; 499 };
499 } 500 }
500 501
502
503 // security
504
505 public interface Security {
506 public void check(LuanState luan,String name) throws LuanException;
507 }
508
509 private static String SECURITY_KEY = "Io.Security";
510
511 private static void check(LuanState luan,String name) throws LuanException {
512 @SuppressWarnings("unchecked")
513 List<Security> list = (List<Security>)luan.registry().get(SECURITY_KEY);
514 if( list==null )
515 return;
516 for( Security s : list ) {
517 s.check(luan,name);
518 }
519 }
520
521 public static void addSecurity(LuanState luan,Security s) {
522 @SuppressWarnings("unchecked")
523 List<Security> list = (List<Security>)luan.registry().get(SECURITY_KEY);
524 if( list==null ) {
525 list = new ArrayList<Security>();
526 luan.registry().put(SECURITY_KEY,list);
527 }
528 list.add(s);
529 }
530
531 public static class DirSecurity implements Security {
532 private final String[] dirs;
533
534 public DirSecurity(LuanState luan,String[] dirs) {
535 this.dirs = dirs;
536 }
537
538 @Override public void check(LuanState luan,String name) throws LuanException {
539 for( String dir : dirs ) {
540 if( name.startsWith(dir) )
541 return;
542 }
543 throw luan.exception("Security violation - '"+name+"' not in allowed directory");
544 }
545 }
546
547
501 private void IoLuan() {} // never 548 private void IoLuan() {} // never
502 } 549 }