Author: ridder
Date: Tue Sep 11 18:18:25 2012
New Revision: 1383505

URL: http://svn.apache.org/viewvc?rev=1383505&view=rev
Log:
CONNECTORS-486: Optionally encrypt the file which the crawler configuration is 
exported to

Modified:
    manifoldcf/trunk/CHANGES.txt
    
manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/ExportConfiguration.java
    
manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/ImportConfiguration.java
    
manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java

Modified: manifoldcf/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/manifoldcf/trunk/CHANGES.txt?rev=1383505&r1=1383504&r2=1383505&view=diff
==============================================================================
--- manifoldcf/trunk/CHANGES.txt (original)
+++ manifoldcf/trunk/CHANGES.txt Tue Sep 11 18:18:25 2012
@@ -3,6 +3,10 @@ $Id$
 
 ======================= 0.7-dev =====================
 
+CONNECTORS-486: Optionally encrypt the file which the crawler configuration
+is exported to.
+(Erlend GarĂ¥sen)
+
 CONNECTORS-523: Build a combined war that can be deployed alone
 on Tomcat and bring all of ManifoldCF's functionality with it.
 (Maciej Lizewski, Karl Wright)

Modified: 
manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/ExportConfiguration.java
URL: 
http://svn.apache.org/viewvc/manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/ExportConfiguration.java?rev=1383505&r1=1383504&r2=1383505&view=diff
==============================================================================
--- 
manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/ExportConfiguration.java
 (original)
+++ 
manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/ExportConfiguration.java
 Tue Sep 11 18:18:25 2012
@@ -29,31 +29,34 @@ public class ExportConfiguration extends
   public static final String _rcsid = "@(#)$Id: ExportConfiguration.java 
988245 2010-08-23 18:39:35Z kwright $";
 
   private final String exportFilename;
+  private final String passCode;
 
-  public ExportConfiguration(String exportFilename)
+  public ExportConfiguration(String exportFilename, String passCode)
   {
     this.exportFilename = exportFilename;
+    this.passCode = passCode;
   }
 
   protected void doExecute(IThreadContext tc) throws ManifoldCFException
   {
-    ManifoldCF.exportConfiguration(tc,exportFilename);
+    ManifoldCF.exportConfiguration(tc,exportFilename, passCode);
     Logging.root.info("Configuration exported");
   }
 
   public static void main(String[] args)
   {
-    if (args.length != 1)
+    if (args.length != 1 && args.length != 2)
     {
-      System.err.println("Usage: ExportConfiguration <filename>");
+      System.err.println("Usage: ExportConfiguration <filename> [<passcode>]");
       System.exit(1);
     }
 
     String exportFilename = args[0];
+    String passCode = (args.length == 2) ? args[1] : null;
 
     try
     {
-      ExportConfiguration exportConfiguration = new 
ExportConfiguration(exportFilename);
+      ExportConfiguration exportConfiguration = new 
ExportConfiguration(exportFilename, passCode);
       exportConfiguration.execute();
       System.err.println("Configuration exported");
     }

Modified: 
manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/ImportConfiguration.java
URL: 
http://svn.apache.org/viewvc/manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/ImportConfiguration.java?rev=1383505&r1=1383504&r2=1383505&view=diff
==============================================================================
--- 
manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/ImportConfiguration.java
 (original)
+++ 
manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/ImportConfiguration.java
 Tue Sep 11 18:18:25 2012
@@ -29,31 +29,34 @@ public class ImportConfiguration extends
   public static final String _rcsid = "@(#)$Id: ImportConfiguration.java 
988245 2010-08-23 18:39:35Z kwright $";
 
   private final String importFilename;
+  private final String passCode;
 
-  public ImportConfiguration(String importFilename)
+  public ImportConfiguration(String importFilename, String passCode)
   {
     this.importFilename = importFilename;
+    this.passCode = passCode;
   }
 
   protected void doExecute(IThreadContext tc) throws ManifoldCFException
   {
-    ManifoldCF.importConfiguration(tc,importFilename);
+    ManifoldCF.importConfiguration(tc,importFilename, passCode);
     Logging.root.info("Configuration imported");
   }
 
   public static void main(String[] args)
   {
-    if (args.length != 1)
+    if (args.length != 1 && args.length != 2)
     {
-      System.err.println("Usage: ImportConfiguration <filename>");
+      System.err.println("Usage: ImportConfiguration <filename> [<passcode>]");
       System.exit(1);
     }
 
     String importFilename = args[0];
+    String passCode = (args.length == 2) ? args[1] : null;
 
     try
     {
-      ImportConfiguration importConfiguration = new 
ImportConfiguration(importFilename);
+      ImportConfiguration importConfiguration = new 
ImportConfiguration(importFilename, passCode);
       importConfiguration.execute();
       System.err.println("Configuration imported");
     }

Modified: 
manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java
URL: 
http://svn.apache.org/viewvc/manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java?rev=1383505&r1=1383504&r2=1383505&view=diff
==============================================================================
--- 
manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java
 (original)
+++ 
manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java
 Tue Sep 11 18:18:25 2012
@@ -22,9 +22,30 @@ import org.apache.manifoldcf.core.interf
 import org.apache.manifoldcf.agents.interfaces.*;
 import org.apache.manifoldcf.crawler.interfaces.*;
 import org.apache.manifoldcf.authorities.interfaces.*;
+import org.apache.tools.ant.taskdefs.Zip;
+
 import java.io.*;
+import java.security.GeneralSecurityException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
 import java.util.*;
 
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.CipherOutputStream;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.SecretKeySpec;
+
 public class ManifoldCF extends org.apache.manifoldcf.agents.system.ManifoldCF
 {
   public static final String _rcsid = "@(#)$Id: ManifoldCF.java 996524 
2010-09-13 13:38:01Z kwright $";
@@ -85,6 +106,7 @@ public class ManifoldCF extends org.apac
   protected static final String connectorsConfigurationFileProperty = 
"org.apache.manifoldcf.connectorsconfigurationfile";
   protected static final String databaseSuperuserNameProperty = 
"org.apache.manifoldcf.dbsuperusername";
   protected static final String databaseSuperuserPasswordProperty = 
"org.apache.manifoldcf.dbsuperuserpassword";
+  protected static final String salt = "org.apache.manifoldcf.salt";
 
   /** This object is used to make sure the initialization sequence is atomic.  
Shutdown cannot occur until the system is in a known state. */
   protected static Integer startupLock = new Integer(0);
@@ -1034,9 +1056,10 @@ public class ManifoldCF extends org.apac
     }
     Logging.root.info("Pull-agent successfully shut down");
   }
+  
 
   /** Atomically export the crawler configuration */
-  public static void exportConfiguration(IThreadContext threadContext, String 
exportFilename)
+  public static void exportConfiguration(IThreadContext threadContext, String 
exportFilename, String passCode)
     throws ManifoldCFException
   {
     // The basic idea here is that we open a zip stream, into which we dump 
all the pertinent information in a transactionally-consistent manner.
@@ -1056,10 +1079,42 @@ public class ManifoldCF extends org.apac
     // Create a zip output stream, which is what we will use as a mechanism 
for handling the output data
     try
     {
+      
       OutputStream os = new FileOutputStream(outputFile);
+      
       try
       {
-        java.util.zip.ZipOutputStream zos = new 
java.util.zip.ZipOutputStream(os);
+        
+        java.util.zip.ZipOutputStream zos = null;
+        CipherOutputStream cos = null;
+        
+        // Check whether we need to encrypt the file content:
+        if (passCode != null && passCode.length() > 0)
+        {
+          
+          // Write IV as a prefix:
+          SecureRandom random = new SecureRandom();
+          byte[] iv = new byte[IV_LENGTH];
+          random.nextBytes(iv);
+          os.write(iv);
+          os.flush();
+          
+          Cipher cipher = null; 
+          try
+          {
+            cipher = getCipher(Cipher.ENCRYPT_MODE, passCode, iv);
+          }
+          catch (GeneralSecurityException gse)
+          {
+            throw new ManifoldCFException("Could not encrypt configuratiom 
file: " + gse.getMessage());
+          }
+          
+          cos = new CipherOutputStream(os, cipher);
+          zos = new java.util.zip.ZipOutputStream(cos);
+        }
+        else
+          zos = new java.util.zip.ZipOutputStream(os);
+ 
         try
         {
           // Now, work within a transaction.
@@ -1112,6 +1167,9 @@ public class ManifoldCF extends org.apac
         finally
         {
           zos.close();
+          if (cos != null) {
+            cos.close();
+          }
         }
       }
       finally
@@ -1127,9 +1185,10 @@ public class ManifoldCF extends org.apac
       throw new ManifoldCFException("Error creating configuration file: 
"+e.getMessage(),e);
     }
   }
+  
 
   /** Atomically import a crawler configuration */
-  public static void importConfiguration(IThreadContext threadContext, String 
importFilename)
+  public static void importConfiguration(IThreadContext threadContext, String 
importFilename, String passCode)
     throws ManifoldCFException
   {
     // First, we need a database handle...
@@ -1151,7 +1210,31 @@ public class ManifoldCF extends org.apac
       InputStream is = new FileInputStream(inputFile);
       try
       {
-        java.util.zip.ZipInputStream zis = new 
java.util.zip.ZipInputStream(is);
+        java.util.zip.ZipInputStream zis = null;
+        CipherInputStream cis = null;
+        
+        // Check whether we need to decrypt the file content:
+        if (passCode != null && passCode.length() > 0)
+        {
+          
+          byte[] iv = new byte[IV_LENGTH];
+          is.read(iv);
+
+          Cipher cipher = null; 
+          try
+          {
+            cipher = getCipher(Cipher.DECRYPT_MODE, passCode, iv);
+          }
+          catch (GeneralSecurityException gse)
+          {
+            throw new ManifoldCFException("Could not decrypt configuratiom 
file: " + gse.getMessage());
+          }
+          cis = new CipherInputStream(is, cipher);
+          zis = new java.util.zip.ZipInputStream(cis);
+        }
+        else
+          zis = new java.util.zip.ZipInputStream(is);
+
         try
         {
           // Now, work within a transaction.
@@ -1159,12 +1242,14 @@ public class ManifoldCF extends org.apac
           try
           {
             // Process the entries in the order in which they were recorded.
+            int entries = 0;
             while (true)
             {
               java.util.zip.ZipEntry z = zis.getNextEntry();
               // Stop if there are no more entries
               if (z == null)
                 break;
+              entries++;
               // Get the name of the entry
               String name = z.getName();
               if (name.equals("outputs"))
@@ -1180,6 +1265,8 @@ public class ManifoldCF extends org.apac
               zis.closeEntry();
 
             }
+            if (entries == 0 && passCode != null && passCode.length() > 0)
+              throw new ManifoldCFException("Cannot read configuration file. 
Please check your passcode and/or SALT value.");
             // All done!!
           }
           catch (ManifoldCFException e)
@@ -1200,6 +1287,9 @@ public class ManifoldCF extends org.apac
         finally
         {
           zis.close();
+          if (cis != null) {
+            cis.close();
+          }
         }
       }
       finally
@@ -3531,8 +3621,28 @@ public class ManifoldCF extends org.apac
     
   }
 
-  // End of connection API code
+  private static final int IV_LENGTH = 16;
   
+  private static Cipher getCipher(final int mode, final String passCode, final 
byte[] iv) throws GeneralSecurityException,
+    ManifoldCFException
+  {
+    final String saltValue = getProperty(salt);
+
+    if (saltValue == null || saltValue.length() == 0)
+      throw new ManifoldCFException("Missing required SALT value");
+    
+    SecretKeyFactory factory = 
SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
+    KeySpec keySpec = new PBEKeySpec(passCode.toCharArray(), 
saltValue.getBytes(), 1024, 128);
+    SecretKey secretKey = factory.generateSecret(keySpec);
+
+    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+    SecretKeySpec key = new SecretKeySpec(secretKey.getEncoded(), "AES");
+    IvParameterSpec parameterSpec = new IvParameterSpec(iv);
+    cipher.init(mode, key, parameterSpec);
+    return cipher;
+  }
   
+  // End of connection API code
+
 }
 


Reply via email to