summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2015-10-29 15:58:12 +0100
committerSimon Rettberg2015-10-29 15:58:12 +0100
commit6ccbc9791369440bef65a136c7c30ae3a33b8534 (patch)
treea94be8ceba9181b2e31bc1ad3d0e194a5c2e9013
parent[LdapSearch] Fix NPE (diff)
downloadtmlite-bwlp-6ccbc9791369440bef65a136c7c30ae3a33b8534.tar.gz
tmlite-bwlp-6ccbc9791369440bef65a136c7c30ae3a33b8534.tar.xz
tmlite-bwlp-6ccbc9791369440bef65a136c7c30ae3a33b8534.zip
[PortScan] Try to verify remote certificate
-rw-r--r--src/main/java/org/openslx/taskmanager/tasks/PortScan.java87
1 files changed, 73 insertions, 14 deletions
diff --git a/src/main/java/org/openslx/taskmanager/tasks/PortScan.java b/src/main/java/org/openslx/taskmanager/tasks/PortScan.java
index b525df6..edc9e36 100644
--- a/src/main/java/org/openslx/taskmanager/tasks/PortScan.java
+++ b/src/main/java/org/openslx/taskmanager/tasks/PortScan.java
@@ -1,16 +1,22 @@
package org.openslx.taskmanager.tasks;
+import java.io.File;
+import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.commons.io.FileUtils;
import org.openslx.satserver.util.Exec;
import org.openslx.taskmanager.api.AbstractTask;
@@ -22,9 +28,15 @@ public class PortScan extends AbstractTask
private String host;
@Expose
private int[] ports;
+ @Expose
+ private String certificate;
private Output status = new Output();
+ private String certFile = null;
+
+ private static final Pattern verifyPattern = Pattern.compile( "^\\s*verify return code:\\s+(\\d+)(\\D|$)", Pattern.CASE_INSENSITIVE );;
+
@Override
protected boolean initTask()
{
@@ -44,13 +56,29 @@ public class PortScan extends AbstractTask
@Override
protected boolean execute()
{
- ExecutorService tp = Executors.newFixedThreadPool( ports.length > 6 ? 6 : ports.length );
+ // Create usable cert file if possible
+ File tmpFile = null;
+ if ( certificate == null || certificate.isEmpty() || certificate.equals( "default" ) ) {
+ certFile = CreateLdapConfig.DEFAULT_CA_BUNDLE;
+ } else {
+ try {
+ tmpFile = File.createTempFile( "bwlp-", ".pem" );
+ FileUtils.writeStringToFile( tmpFile, certificate, StandardCharsets.UTF_8 );
+ } catch ( IOException e ) {
+ status.addMessage( "Error creating temporary file for certificate: " + e.getMessage() );
+ return false;
+ }
+ certFile = tmpFile.getAbsolutePath();
+ }
+ // Execute scan in parallel (4 tasks) to speed things up
+ ExecutorService tp = Executors.newFixedThreadPool( ports.length > 4 ? 4 : ports.length );
+ final List<Result> results = new ArrayList<>();
for ( final int port : ports ) {
tp.submit( new Callable<Object>() {
@Override
public Object call() throws Exception
{
- status.ports.add( testPort( port ) );
+ results.add( testPort( port ) );
return null;
}
} );
@@ -61,6 +89,10 @@ public class PortScan extends AbstractTask
} catch ( InterruptedException e ) {
// ...
}
+ if ( tmpFile != null ) {
+ tmpFile.delete();
+ }
+ status.ports = results;
return true;
}
@@ -69,34 +101,55 @@ public class PortScan extends AbstractTask
boolean open = false;
final AtomicReference<String> fingerprint = new AtomicReference<>();
final AtomicReference<String> notAfter = new AtomicReference<>();
- final StringBuffer sb = new StringBuffer();
+ final AtomicInteger verifyResult = new AtomicInteger( -1 );
+ final StringBuffer messages = new StringBuffer();
+ final StringBuffer certList = new StringBuffer();
try {
Socket sock = new Socket();
sock.connect( new InetSocketAddress( this.host, port ), 1200 );
open = true;
- sb.append( "Found open port " + port );
+ messages.append( "Found open port " + port );
sock.close();
} catch ( Exception e ) {
if ( !open ) {
- sb.append( "Found closed port " + port );
+ messages.append( "Found closed port " + port );
}
}
if ( open ) {
String str = this.host.replaceAll( "[^a-zA-Z0-9\\.\\-_]", "" ) + ":" + port;
// Is open, see if it is running SSL
- Exec.syncAt( 2, new Exec.ExecCallback() {
+ Exec.syncAt( 4, new Exec.ExecCallback() {
+ private boolean inCert = false;
@Override
public void processStdOut( String line )
{
if ( line.startsWith( "notAfter=" ) ) {
notAfter.set( line.substring( 9 ) );
- sb.append( "\nCertificate valid until " + notAfter.get() );
+ messages.append( "\nCertificate valid until " + notAfter.get() );
}
if ( line.startsWith( "SHA1 Fingerprint=" ) ) {
fingerprint.set( line.substring( 17 ) );
- sb.append( "\nCertificate fingerprint: " + fingerprint.get() );
+ messages.append( "\nCertificate fingerprint: " + fingerprint.get() );
+ }
+ if ( !inCert && line.equals( "-----BEGIN CERTIFICATE-----" ) ) {
+ inCert = true;
+ }
+ if ( inCert ) {
+ if ( line.equals( "-----END CERTIFICATE-----" ) ) {
+ inCert = false;
+ }
+ certList.append( line );
+ certList.append( '\n' );
+ }
+ Matcher m;
+ if ( verifyResult.get() == -1 && null != ( m = verifyPattern.matcher( line ) ) && m.find() ) {
+ try {
+ verifyResult.set( Integer.parseInt( m.group( 1 ) ) );
+ } catch ( Exception e ) {
+ }
+ messages.append( "\nVerify result: " + verifyResult.get() );
}
}
@@ -107,11 +160,12 @@ public class PortScan extends AbstractTask
}
}, "/", "/bin/sh", "-c",
- "openssl s_client -showcerts -connect " + str + " </dev/null 2> /dev/null "
+ "openssl s_client -CAfile '" + certFile + "' -showcerts -connect " + str + " </dev/null 2> /dev/null; "
+ + "openssl s_client -connect " + str + " </dev/null 2> /dev/null "
+ " | openssl x509 -noout -enddate -fingerprint -sha1 2>&1" );
}
- status.addMessage( sb.toString() );
- return new Result( port, open, fingerprint.get(), notAfter.get() );
+ status.addMessage( messages.toString() );
+ return new Result( port, open, fingerprint.get(), notAfter.get(), verifyResult.get(), certList.toString() );
}
/**
@@ -120,7 +174,8 @@ public class PortScan extends AbstractTask
private static class Output
{
protected String messages = null;
- protected List<Result> ports = Collections.synchronizedList( new ArrayList<Result>() );
+ @SuppressWarnings( "unused" )
+ protected List<Result> ports = null;
private void addMessage( String str )
{
@@ -139,13 +194,17 @@ public class PortScan extends AbstractTask
protected final boolean open;
protected final String certFingerprint;
protected final String notAfter;
+ protected final int verifyResult;
+ protected final String certificateChain;
- public Result( int port, boolean open, String fingerprint, String notAfter )
+ public Result( int port, boolean open, String fingerprint, String notAfter, int verifyResult, String certificateChain )
{
this.port = port;
this.open = open;
this.certFingerprint = fingerprint;
this.notAfter = notAfter;
+ this.verifyResult = verifyResult;
+ this.certificateChain = certificateChain;
}
}