package org.openslx.taskmanager.tasks; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.io.FilenameUtils; import org.openslx.satserver.util.Archive; import org.openslx.satserver.util.Util; import org.openslx.taskmanager.api.AbstractTask; import com.google.gson.annotations.Expose; public class ListArchive extends AbstractTask { @Expose private String file; /* * Own vars/constants not being deserialized */ protected static final String[] ALLOWED_DIRS = { "/tmp/", "/opt/openslx/" }; private Output status = new Output(); /* * Code */ @Override protected boolean execute() { ArchiveInputStream archive; try { archive = Archive.getArchiveInputStream( this.file ); } catch ( FileNotFoundException e1 ) { status.error = e1.getMessage(); status.errorCode = Output.ErrorCode.NOT_FOUND; return false; } catch ( IllegalArgumentException e1 ) { status.error = e1.getMessage(); status.errorCode = Output.ErrorCode.UNKNOWN_ERROR; return false; } catch ( ArchiveException e1 ) { status.error = e1.getMessage(); status.errorCode = Output.ErrorCode.UNKNOWN_FORMAT; return false; } List entries = new ArrayList<>(); ArchiveEntry archiveEntry; try { // Iterate over every entry while ( ( archiveEntry = archive.getNextEntry() ) != null ) { if ( !archive.canReadEntryData( archiveEntry ) ) continue; Output.Entry entry = new Output.Entry(); entry.name = archiveEntry.getName(); entry.isdir = archiveEntry.isDirectory(); entry.size = archiveEntry.getSize(); entries.add( entry ); } } catch ( IOException e ) { return false; } status.entries = entries; return true; } @Override protected boolean initTask() { this.setStatusObject( this.status ); if ( this.file == null || this.file.length() == 0 || this.file.charAt( 0 ) != '/' ) { status.error = "Need absolute path."; status.errorCode = Output.ErrorCode.INVALID_DIRECTORY; return false; } this.file = FilenameUtils.normalize( this.file ); if ( this.file == null || !Util.startsWith( this.file, ALLOWED_DIRS ) ) { status.error = "File not in allowed directory"; status.errorCode = Output.ErrorCode.INVALID_DIRECTORY; return false; } return true; } @SuppressWarnings( "unused" ) private static class Output { protected String error = null; protected enum ErrorCode { NOT_FOUND, UNKNOWN_FORMAT, UNKNOWN_ERROR, INVALID_DIRECTORY }; protected ErrorCode errorCode = null; protected List entries = null; public static class Entry { protected String name = null; protected boolean isdir = false; protected long size = -1; } } }