package org.openslx.taskmanager.tasks; import java.io.File; import java.nio.file.Files; import java.nio.file.Paths; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.openslx.satserver.util.Util; import org.openslx.taskmanager.api.AbstractTask; import com.google.gson.annotations.Expose; public class Symlink extends AbstractTask { protected static final String[] ALLOWED_DIRS = { "/srv/openslx/www/boot/" }; @Expose private String target = null; @Expose private String linkname = null; private Output status = new Output(); @Override protected boolean initTask() { if ( Util.isEmpty( this.linkname ) ) { status.error = "Link name empty"; return false; } if ( this.linkname.endsWith( "/" ) ) { status.error = "Link name ends with slash"; return false; } this.setStatusObject( status ); if ( Util.isEmpty( this.target ) ) { status.error = "Target empty"; return false; } this.linkname = FilenameUtils.normalize( this.linkname ); if ( !Util.startsWith( this.linkname, ALLOWED_DIRS ) ) { status.error = "Link name not in allowed directory"; return false; } if ( !this.target.startsWith( "/" ) ) { this.target = new File( this.linkname ).getParent() + "/" + this.target; } this.target = FilenameUtils.normalize( this.target ); if ( !Util.startsWith( this.target, ALLOWED_DIRS ) ) { status.error = "Target not in allowed directory"; return false; } return true; } @Override protected boolean execute() { FileUtils.deleteQuietly( new File( linkname ) ); if ( this.target != null ) { try { Files.createSymbolicLink( Paths.get( this.linkname ), Paths.get( this.target ) ); } catch ( Exception e ) { status.error = e.toString(); return false; } } return true; } /** * Output - contains additional status data of this task */ @SuppressWarnings( "unused" ) private static class Output { protected String error = null; } }