package org.srdbs.core; import org.apache.log4j.Logger; import org.srdbs.scheduler.RunBackupJob; import org.srdbs.scheduler.RunScheduler; import org.srdbs.sftp.Sftp; import org.srdbs.split.FileData; import org.srdbs.split.MYSpFile; import org.srdbs.split.MyFile; import java.text.DateFormat; import java.util.Date; import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.*; import java.security.SecureRandom; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import static org.srdbs.split.Split.mySplit; /** * Secure and Redundant Data Backup System. * User: Thilina Piyasundara * Date: 5/25/12 * Time: 10:46 AM * For more details visit : http://www.thilina.org */ public class RunBackup { public static Logger logger = Logger.getLogger("systemsLog"); public static Logger backplogger = Logger.getLogger("backupLog"); public static long fid; private static final int IV_LENGTH = 16; public static String Despath; public static int count; public static String newFileName; public static Date date; public static DateFormat datef; public static int runBackup(String path, final String dest, int compress, int encrypt) { backplogger.info("Running the backup log."); backplogger.info("Running the backup for : " + dest + " (compress " + compress + ", encrypt " + encrypt + ")"); DbConnect dbConnect = new DbConnect(); int noOfFiles = 0; List<MyFile> listOfFiles = null; listOfFiles = FileData.Read(path); List<MYSpFile> dListOfFiles = null; for (final MyFile file : listOfFiles) { //if both compression and encryption enable if ((compress != 0) && (encrypt != 0)) { String fzip = file.getName() + ".zip"; try { compressFile(path + "/" + file.getName()); } catch (Exception e) { e.printStackTrace(); } String fileName = path + "/" + fzip; String tempFileName = fileName + ".enc"; try { copy(Cipher.ENCRYPT_MODE, fileName, tempFileName, "password12345678"); System.out.println("Success. Find encrypted and decripted files in current directory"); logger.info("Success. Find encrypted and decripted files in current directory" + fzip); } catch (Exception e) { e.printStackTrace(); } String fzipencrypt = file.getName() + ".zip.enc"; newFileName = fzipencrypt; try { Despath = CreateFolder(dest); } catch (Exception e) { e.printStackTrace(); } long FSize = FileData.getFileSize(path + "/" + fzip); int bandwidthSum = 1024 * (((int) (Math.random() * 10) % 9) + 10); int packetVal = (int) (FSize / bandwidthSum); backplogger.info("Packet size : " + packetVal + " File size : " + file.getSize() + " c1 : " + Global.c1Bandwidth + " c2 : " + Global.c2Bandwidth + " c3 : " + Global.c3Bandwidth); count = mySplit(path + Global.fs + fzipencrypt, Despath + Global.fs + fzipencrypt, packetVal); File f = new File(path + Global.fs + fzip); File f1 = new File(path + Global.fs + fzipencrypt); f.delete(); f1.delete(); backplogger.info("Split Files in the file path of : " + path + Global.fs + file.getName() + " in to " + count + " parts."); noOfFiles++; try { dbConnect.saveFiles(fzipencrypt, file.getSize(), file.getHash(), file.getcDate()); backplogger.info("Save full file details to the database."); } catch (Exception e) { backplogger.error("Database connection error : " + e); } backplogger.info("Compressing and Encrypting the backup files : " + file.getName()); } //if compression is enabled. if ((compress != 0) && (encrypt == 0)) { String fzip = file.getName() + ".zip"; try { compressFile(path + "/" + file.getName()); } catch (Exception e) { e.printStackTrace(); } String fzipencrypt = file.getName() + ".zip"; newFileName = fzipencrypt; try { Despath = CreateFolder(dest); } catch (Exception e) { e.printStackTrace(); } long FSize = FileData.getFileSize(path + "/" + fzip); int bandwidthSum = 1024 * (((int) (Math.random() * 10) % 9) + 10); int packetVal = (int) (FSize / bandwidthSum); backplogger.info("Packet size : " + packetVal + " File size : " + file.getSize() + " c1 : " + Global.c1Bandwidth + " c2 : " + Global.c2Bandwidth + " c3 : " + Global.c3Bandwidth); count = mySplit(path + Global.fs + fzipencrypt, Despath + Global.fs + fzipencrypt, packetVal); File f = new File(path + Global.fs + fzipencrypt); f.delete(); backplogger.info("Split Files in the file path of : " + path + Global.fs + file.getName() + " in to " + count + " parts."); noOfFiles++; try { dbConnect.saveFiles(fzip, file.getSize(), file.getHash(), file.getcDate()); backplogger.info("Save full file details to the database."); } catch (Exception e) { backplogger.error("Database connection error : " + e); } backplogger.info("Compressing the backup files : " + file.getName()); } // if encryption is enabled. if ((encrypt != 0) && (compress == 0)) { String fzip = file.getName(); String fileName = path + "/" + fzip; String tempFileName = fileName + ".enc"; try { copy(Cipher.ENCRYPT_MODE, fileName, tempFileName, "password12345678"); System.out.println("Success. Find encrypted and decripted files in current directory"); logger.info("Success. Find encrypted and decripted files in current directory" + fzip); } catch (Exception e) { e.printStackTrace(); } String fzipencrypt = file.getName() + ".enc"; newFileName = fzipencrypt; try { Despath = CreateFolder(dest); } catch (Exception e) { e.printStackTrace(); } long FSize = FileData.getFileSize(path + "/" + fzip); int bandwidthSum = 1024 * (((int) (Math.random() * 10) % 9) + 10); int packetVal = (int) (FSize / bandwidthSum); backplogger.info("Packet size : " + packetVal + " File size : " + file.getSize() + " c1 : " + Global.c1Bandwidth + " c2 : " + Global.c2Bandwidth + " c3 : " + Global.c3Bandwidth); count = mySplit(path + Global.fs + fzipencrypt, Despath + Global.fs + fzipencrypt, packetVal); File f = new File(path + Global.fs + fzipencrypt); f.delete(); backplogger.info("Split Files in the file path of : " + path + Global.fs + file.getName() + " in to " + count + " parts."); noOfFiles++; try { dbConnect.saveFiles(fzipencrypt, file.getSize(), file.getHash(), file.getcDate()); backplogger.info("Save full file details to the database."); } catch (Exception e) { backplogger.error("Database connection error : " + e); } backplogger.info("Encrypting the backup files : " + file.getName()); } if ((encrypt == 0) && (compress == 0)) { String fnormal = file.getName(); newFileName = fnormal; try { Despath = CreateFolder(dest); } catch (Exception e) { e.printStackTrace(); } long FSize = FileData.getFileSize(path + "/" + fnormal); int bandwidthSum = 1024 * (((int) (Math.random() * 10) % 9) + 10); int packetVal = (int) (FSize / bandwidthSum); backplogger.info("Packet size : " + packetVal + " File size : " + file.getSize() + " c1 : " + Global.c1Bandwidth + " c2 : " + Global.c2Bandwidth + " c3 : " + Global.c3Bandwidth); count = mySplit(path + Global.fs + fnormal, Despath + Global.fs + fnormal, packetVal); backplogger.info("Split Files in the file path of : " + path + Global.fs + file.getName() + " in to " + count + " parts."); noOfFiles++; try { dbConnect.saveFiles(file.getName(), file.getSize(), file.getHash(), file.getcDate()); backplogger.info("Save full file details to the database."); } catch (Exception e) { backplogger.error("Database connection error : " + e); } } // RAID int[] raidArray = Sftp.raid(count); backplogger.info("Raid is done."); //TODO remove this for (int j = 0; j < raidArray.length; ) { backplogger.info("Packet " + (j + 2) / 2 + ": Orignal: " + raidArray[j] + " , " + "Raid: " + raidArray[j + 1]); j = j + 2; } try { dListOfFiles = FileData.ReadSPFile(Despath, count, raidArray); for (MYSpFile file2 : dListOfFiles) { dbConnect.saveSPFiles(file2.getFid(), file2.getName(), file2.getSize(), file2.getHash(), file2.getCloud(), file2.getRCloud()); fid = file2.getFid(); } backplogger.info("Save split file details to the database. "); } catch (Exception e) { backplogger.error("Database connection error : " + e); } date = new Date(); datef = new SimpleDateFormat("yyMMddHHmmss"); backplogger.info("Uploading " + newFileName + " to cloud 1."); Sftp.upload(Despath + Global.fs + newFileName, fid, datef.format(date)); backplogger.info("Uploading " + newFileName + " to cloud 2."); Sftp.upload1(Despath + Global.fs + newFileName, fid, datef.format(date)); backplogger.info("Uploading " + newFileName + " to cloud 3."); Sftp.upload2(Despath + Global.fs + newFileName, fid, datef.format(date)); Sftp.clearcloud1(); Sftp.clearcloud2(); Sftp.clearcloud3(); File delfol = new File(Despath); boolean isDeleted = deleteDir(delfol); dbConnect.InsertStatus("isankatest","isankatest","upload done"); System.out.println("Folder is Deleted : "+ isDeleted); backplogger.info("Folder is Deleted : "+ isDeleted); } backplogger.info("Split " + noOfFiles + " Files in the file path of : " + path); return 0; } public static void compressFile(String path) { String D_path = path + ".zip"; try { try (ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(D_path)))) { byte[] data = new byte[1000]; BufferedInputStream in = new BufferedInputStream(new FileInputStream(path)); int count; out.putNextEntry(new ZipEntry("outFile.zip")); while ((count = in.read(data, 0, 1000)) != -1) { out.write(data, 0, count); } in.close(); out.flush(); } System.out.println("Your file is zipped"); } catch (Exception e) { e.printStackTrace(); } } public static String CreateFolder(String path) throws Exception { String fldate; DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); java.util.Date date = new java.util.Date(); fldate = dateFormat.format(date); String strDirectoy = path + "/" + fldate; // Create one directory boolean success = ( new File(strDirectoy)).mkdir(); if (success) { System.out.println("Directory: " + strDirectoy + " created"); } return strDirectoy; } public static void copy(int mode, String inputFile, String outputFile, String password) throws Exception { BufferedInputStream is = new BufferedInputStream(new FileInputStream(inputFile)); BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(outputFile)); if (mode == Cipher.ENCRYPT_MODE) { encrypt(is, os, password); } else if (mode == Cipher.DECRYPT_MODE) { //decrypt(is, os, password); } else throw new Exception("unknown mode"); is.close(); os.close(); } public static void encrypt(InputStream in, OutputStream out, String password) throws Exception { SecureRandom r = new SecureRandom(); byte[] iv = new byte[IV_LENGTH]; r.nextBytes(iv); out.write(iv); //write IV as a prefix out.flush(); //System.out.println(">>>>>>>>written"+Arrays.toString(iv)); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //"DES/ECB/PKCS5Padding";"AES/CBC/PKCS5Padding";"AES/CFB8/NoPadding" SecretKeySpec keySpec = new SecretKeySpec(password.getBytes(), "AES"); IvParameterSpec ivSpec = new IvParameterSpec(iv); cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); out = new CipherOutputStream(out, cipher); byte[] buf = new byte[1024]; int numRead = 0; while ((numRead = in.read(buf)) >= 0) { out.write(buf, 0, numRead); } out.close(); } public static boolean delete(String path) { boolean DeleteCheck = false; File folder = new File(path); String files1; File[] listOfFiles = folder.listFiles(); for (int i = 0; i < listOfFiles.length; i++) { files1 = listOfFiles[i].getName(); String Full_path = path +"/"+files1; File DelFile = new File(Full_path); DeleteCheck = DelFile.delete(); if(!DeleteCheck){ System.out.println("File is not Deleted :" + files1); logger.error("File is not Deleted :" + files1); } else{ System.out.println("Delete File :" + files1); logger.info("Delete File :" + files1); } } return DeleteCheck; } public static boolean deleteDir(File dir) { if (dir.isDirectory()) { String[] children = dir.list(); for (int i=0; i<children.length; i++) { boolean success = deleteDir(new File(dir, children[i])); if (!success) { System.out.println("Folder is not Deleted : "+ dir); backplogger.error("Folder is not Deleted : " + dir); return false; } } } // The directory is now empty so delete it return dir.delete(); } }