From ecb072b02e1a70555db0fdf4ed47375d3080a074 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 18 Nov 2014 18:40:49 +0100 Subject: Many improvements and additions: - Added task+script for lighttpd https config - Added task for reloading proxy config - ldapsearch now supports searching for specific user - DownloadFile now supports checking file integrity through optional gpg signature --- src/main/java/org/openslx/satserver/util/Exec.java | 20 ++-- .../org/openslx/satserver/util/ProxyHandler.java | 35 +++++-- src/main/java/org/openslx/satserver/util/Util.java | 19 ++-- .../openslx/taskmanager/tasks/DownloadFile.java | 47 +++++++-- .../org/openslx/taskmanager/tasks/LdapSearch.java | 8 +- .../openslx/taskmanager/tasks/LighttpdHttps.java | 105 +++++++++++++++++++++ .../org/openslx/taskmanager/tasks/ReloadProxy.java | 26 +++++ 7 files changed, 226 insertions(+), 34 deletions(-) create mode 100644 src/main/java/org/openslx/taskmanager/tasks/LighttpdHttps.java create mode 100644 src/main/java/org/openslx/taskmanager/tasks/ReloadProxy.java (limited to 'src/main') diff --git a/src/main/java/org/openslx/satserver/util/Exec.java b/src/main/java/org/openslx/satserver/util/Exec.java index e7b27da..1f810eb 100644 --- a/src/main/java/org/openslx/satserver/util/Exec.java +++ b/src/main/java/org/openslx/satserver/util/Exec.java @@ -6,17 +6,23 @@ import java.io.IOException; public class Exec { + /** + * Run command, return exit status of process, or -1 on error + * + * @param command Command and arguments + * @return exit code + */ public static int sync( String... command ) { ProcessBuilder pb = new ProcessBuilder( command ); pb.directory( new File( "/" ) ); - Process p; - try { - p = pb.start(); - return p.waitFor(); - } catch ( IOException | InterruptedException e ) { - return -1; - } + Process p; + try { + p = pb.start(); + return p.waitFor(); + } catch ( IOException | InterruptedException e ) { + return -1; + } } } diff --git a/src/main/java/org/openslx/satserver/util/ProxyHandler.java b/src/main/java/org/openslx/satserver/util/ProxyHandler.java index 9a702fe..f70a496 100644 --- a/src/main/java/org/openslx/satserver/util/ProxyHandler.java +++ b/src/main/java/org/openslx/satserver/util/ProxyHandler.java @@ -3,19 +3,36 @@ package org.openslx.satserver.util; import org.openslx.network.ProxyConfiguration; /** - * Class for handling proxy configuration in task manager. Just configure proxy - * setting system wide, if it was not done already. + * Class for handling proxy configuration in task manager. + * * @author bjoern - * + * */ -public class ProxyHandler { +public class ProxyHandler +{ private static boolean hasDoneConfigProxy = false; + private static final Object proxyMutex = new Object(); - public static void configProxy() { - // Just configuring proxy settings system wide, if not done already. - if (!hasDoneConfigProxy) { - ProxyConfiguration.configProxy(); - hasDoneConfigProxy = true; + /** + * Do proxy setup if not done already + */ + public static void configProxy() + { + configProxy( false ); + } + + /** + * Do proxy setup if not done already, or if explicitly forced. + * + * @param force Do setup even if already done + */ + public static synchronized void configProxy( boolean force ) + { + synchronized ( proxyMutex ) { + if ( !hasDoneConfigProxy || force ) { + ProxyConfiguration.configProxy(); + hasDoneConfigProxy = true; + } } } } diff --git a/src/main/java/org/openslx/satserver/util/Util.java b/src/main/java/org/openslx/satserver/util/Util.java index fe7eb6e..2df4c73 100644 --- a/src/main/java/org/openslx/satserver/util/Util.java +++ b/src/main/java/org/openslx/satserver/util/Util.java @@ -5,6 +5,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.charset.StandardCharsets; import org.apache.commons.io.FileUtils; @@ -30,6 +31,7 @@ public class Util /** * Close all given Closables. Can handle null references. + * * @param streams one or more closables/streams */ public static void multiClose( Closeable... streams ) @@ -64,14 +66,15 @@ public class Util } return true; } - - public static String readFileToString(String file) + + public static String readFileToString( String file ) throws IOException { - try { - return FileUtils.readFileToString( new File( file ) ); - } catch ( Exception e ) { - return null; - } + return FileUtils.readFileToString( new File( file ), StandardCharsets.UTF_8 ); } - + + public static void writeStringToFile( File file, String string ) throws IOException + { + FileUtils.writeStringToFile( file, string, StandardCharsets.UTF_8 ); + } + } diff --git a/src/main/java/org/openslx/taskmanager/tasks/DownloadFile.java b/src/main/java/org/openslx/taskmanager/tasks/DownloadFile.java index ac9ea0e..1129200 100644 --- a/src/main/java/org/openslx/taskmanager/tasks/DownloadFile.java +++ b/src/main/java/org/openslx/taskmanager/tasks/DownloadFile.java @@ -6,9 +6,11 @@ import java.io.FileOutputStream; import java.io.IOException; import java.net.URL; import java.net.URLConnection; +import java.nio.charset.StandardCharsets; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; +import org.openslx.satserver.util.Exec; import org.openslx.satserver.util.ProxyHandler; import org.openslx.satserver.util.Util; import org.openslx.taskmanager.api.AbstractTask; @@ -22,11 +24,13 @@ public class DownloadFile extends AbstractTask private String url = null; @Expose private String destination = null; + @Expose + private String gpg = null; private Output status = new Output(); private static final String[] ALLOWED_DIRS = - { "/srv/openslx/www/boot/" }; + { "/srv/openslx/www/boot/", "/tmp/" }; @Override protected boolean initTask() @@ -50,30 +54,57 @@ public class DownloadFile extends AbstractTask URLConnection connection = null; BufferedInputStream in = null; FileOutputStream fout = null; - + // Handle proxy settings before opening connection for downloading. ProxyHandler.configProxy(); try { - File dest = new File( this.destination ); - FileUtils.forceMkdir( new File( dest.getParent() ) ); - FileUtils.deleteQuietly( dest ); + File tmpFile = File.createTempFile( "bwlp-", ".tmp", null ); connection = new URL( this.url ).openConnection(); in = new BufferedInputStream( connection.getInputStream() ); - fout = new FileOutputStream( dest ); + fout = new FileOutputStream( tmpFile ); status.size = connection.getContentLengthLong(); + if ( status.size <= 0 ) // If size is unknown, fake progress... + status.progress = 10; - final byte data[] = new byte[ 9000 ]; + final byte data[] = new byte[ 90000 ]; int count; while ( ( count = in.read( data, 0, data.length ) ) != -1 ) { fout.write( data, 0, count ); status.complete += count; if ( status.size > 0 ) status.progress = (int) ( 100l * status.complete / status.size ); + else if ( status.progress < 99 && System.currentTimeMillis() % 20 == 0 ) + status.progress++; + } + fout.close(); + // If we have a gpg sig, validate + if ( this.gpg != null ) { + File gpgTempFile = null; + try { + gpgTempFile = File.createTempFile( "bwlp-", ".gpg", null ); + Util.writeStringToFile( gpgTempFile, this.gpg ); + } catch ( Exception e ) { + status.error = "Could not create temporary file for gpg signature"; + return false; + } + if ( 0 != Exec.sync( "gpg", "--homedir", "/opt/openslx/gpg", "--verify", gpgTempFile.getAbsolutePath(), tmpFile.getAbsolutePath() ) ) { + status.error = "GPG signature of downloaded file not valid!"; + return false; + } + gpgTempFile.delete(); + } + // Move file to destination + File dest = new File( this.destination ); + FileUtils.forceMkdir( new File( dest.getParent() ) ); + if ( dest.exists() ) + dest.delete(); + if ( !tmpFile.renameTo( dest ) ) { + status.error = "Could not move downloaded file to destination directory!"; + return false; } return true; } catch ( IOException e ) { status.error = "Download error: " + e.toString(); - FileUtils.deleteQuietly( new File( this.destination ) ); return false; } finally { Util.multiClose( in, fout ); diff --git a/src/main/java/org/openslx/taskmanager/tasks/LdapSearch.java b/src/main/java/org/openslx/taskmanager/tasks/LdapSearch.java index 157b5e1..dbb76b1 100644 --- a/src/main/java/org/openslx/taskmanager/tasks/LdapSearch.java +++ b/src/main/java/org/openslx/taskmanager/tasks/LdapSearch.java @@ -93,9 +93,9 @@ public class LdapSearch extends SystemCommandTask exitCode = 0; if ( exitCode != 0 ) status.addMessage( "Exit code is " + exitCode ); - if ( exitCode == 0 && this.userCount < 4 ) + if ( exitCode == 0 && this.userCount < 4 && !this.getDn ) status.addMessage( "Found less than 4 users. Are you sure you got the right credentials." ); - return this.userCount >= 4; + return this.userCount >= 4 || (this.getDn && status.dn != null); } @Override @@ -105,6 +105,10 @@ public class LdapSearch extends SystemCommandTask status.addMessage( "Found AD user " + line.substring( 16 ) + " :-)" ); this.userCount++; } + if ( line.startsWith( "sAMAccountName:: " ) ) { + status.addMessage( "Found AD user " + line.substring( 17 ) + " :-)" ); + this.userCount++; + } if ( this.getDn && line.startsWith( "dn: " ) ) { status.dn = line.substring( 4 ); } diff --git a/src/main/java/org/openslx/taskmanager/tasks/LighttpdHttps.java b/src/main/java/org/openslx/taskmanager/tasks/LighttpdHttps.java new file mode 100644 index 0000000..1b5e8e8 --- /dev/null +++ b/src/main/java/org/openslx/taskmanager/tasks/LighttpdHttps.java @@ -0,0 +1,105 @@ +package org.openslx.taskmanager.tasks; + +import java.io.File; + +import org.openslx.satserver.util.Exec; +import org.openslx.satserver.util.Util; +import org.openslx.taskmanager.api.AbstractTask; + +import com.google.gson.annotations.Expose; + +public class LighttpdHttps extends AbstractTask +{ + + private Output status = new Output(); + + @Expose + private String importcert = null; + @Expose + private String importkey = null; + + @Expose + private String proxyip = null; + + @Override + protected boolean initTask() + { + this.setStatusObject( this.status ); + return true; + } + + @Override + protected boolean execute() + { + if ( this.importcert != null && this.importkey != null ) + return createFromInput(); + if ( this.proxyip != null ) + return createRandom(); + return disableHttps(); + } + + private boolean createRandom() + { + int ret = Exec.sync( "sudo", "-n", "-u", "root", "/opt/taskmanager/scripts/install-https", "--random", this.proxyip ); + if ( ret != 0 ) { + status.error = "generator exited with code " + ret; + return false; + } + return true; + } + + private boolean createFromInput() + { + // Import supplied certificate and key. Test if they are valid first + File tmpKey = null; + File tmpCert = null; + try { + try { + tmpKey = File.createTempFile( "bwlp-", ".pem" ); + tmpCert = File.createTempFile( "bwlp-", ".pem" ); + Util.writeStringToFile( tmpCert, this.importcert ); + Util.writeStringToFile( tmpKey, this.importkey ); + } catch ( Exception e ) { + status.error = "Could not create temporary files!"; + return false; + } + int ret; + ret = Exec.sync( "/opt/taskmanager/scripts/install-https", "--test", tmpKey.getAbsolutePath(), tmpCert.getAbsolutePath() ); + if ( ret != 0 ) { + status.error = "Given key and certificate do not match, or have invalid format (exit code: " + ret + ")"; + return false; + } + ret = Exec.sync( "sudo", "-n", "-u", "root", "/opt/taskmanager/scripts/install-https", "--import", tmpKey.getAbsolutePath(), tmpCert.getAbsolutePath() ); + if ( ret != 0 ) { + status.error = "import exited with code " + ret; + return false; + } + return true; + } finally { + if ( tmpKey != null ) + tmpKey.delete(); + if ( tmpCert != null ) + tmpCert.delete(); + } + } + + private boolean disableHttps() + { + int ret = Exec.sync( "sudo", "-n", "-u", "root", "/opt/taskmanager/scripts/install-https", "--disable" ); + if ( ret != 0 ) { + status.error = "import exited with code " + ret; + return false; + } + return true; + } + + /** + * Output - contains additional status data of this task + */ + @SuppressWarnings( "unused" ) + private static class Output + { + protected String error = null; + } + +} diff --git a/src/main/java/org/openslx/taskmanager/tasks/ReloadProxy.java b/src/main/java/org/openslx/taskmanager/tasks/ReloadProxy.java new file mode 100644 index 0000000..b3216dd --- /dev/null +++ b/src/main/java/org/openslx/taskmanager/tasks/ReloadProxy.java @@ -0,0 +1,26 @@ +package org.openslx.taskmanager.tasks; + +import org.openslx.satserver.util.ProxyHandler; +import org.openslx.taskmanager.api.AbstractTask; + +/** + * Just force reloading and setting up proxy configuration. + * Used after modifying settings in the webgui. + */ +public class ReloadProxy extends AbstractTask +{ + + @Override + protected boolean initTask() + { + return true; + } + + @Override + protected boolean execute() + { + ProxyHandler.configProxy( true ); + return true; + } + +} -- cgit v1.2.3-55-g7522