/* * Copyright 2010 Nabeel Mukhtar * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.appspot.bitlyminous.gateway; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import javax.persistence.EntityManager; import javax.persistence.Query; import uk.co.mccann.gsb.engine.util.URLUtils; import uk.co.mccann.gsb.exceptions.GSBException; import uk.co.mccann.gsb.interfaces.GSBDAO; import uk.co.mccann.gsb.interfaces.GSBEngine; import uk.co.mccann.gsb.interfaces.GSBEngineConfiguration; import uk.co.mccann.gsb.interfaces.GSBSession; import uk.co.mccann.gsb.model.CheckURL; import uk.co.mccann.gsb.model.ListURL; import uk.co.mccann.gsb.model.SessionImpl; import com.appspot.bitlyminous.dao.EMF; import com.appspot.bitlyminous.dao.NamedQueries; import com.appspot.bitlyminous.entity.Blacklist; import com.appspot.bitlyminous.entity.Malware; import com.appspot.bitlyminous.entity.Version; /** * The Class GoogleSafeBrowsingGateway. */ public class GoogleSafeBrowsingGateway implements GSBEngine { /** The Constant logger. */ protected static final Logger logger = Logger.getLogger(GoogleSafeBrowsingGateway.class.getCanonicalName()); /** The dao. */ private AppEngineDAO dao = new AppEngineDAO(); /** The config. */ private GSBEngineConfiguration config; /** The session. */ private GSBSession session; /** * Instantiates a new google safe browsing gateway. * * @param apiKey the api key * @param useKey the use key */ public GoogleSafeBrowsingGateway(String apiKey, boolean useKey) { try { GSBEngineConfiguration config = new AppEngineConfigImpl(dao); config.setAPIKey(apiKey); config.useKey(useKey); this.config = config; /* create a new session */ this.session = new SessionImpl(); this.session.startSession(this.config); } catch (Exception e) { logger.log(Level.SEVERE, "Error while starting session.", e); } } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngine#isBlacklisted(java.lang.String) */ public boolean isBlacklisted(String url) throws GSBException { URLUtils urlutils = new URLUtils(); ArrayList<CheckURL> urls = urlutils.getLookupURLs(url); for (CheckURL checkURL : urls) { if (this.dao.locateBlacklistHash(checkURL.getMD5Hash())) { return true; } } return false; } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngine#isMalwarelisted(java.lang.String) */ public boolean isMalwarelisted(String url) throws GSBException { URLUtils urlutils = new URLUtils(); ArrayList<CheckURL> urls = urlutils.getLookupURLs(url); for (CheckURL checkURL : urls) { if (this.dao.locateMalwareHash(checkURL.getMD5Hash())) { return true; } } return false; } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngine#isDangerous(java.lang.String) */ public boolean isDangerous(String url) throws GSBException { /* update lists */ // this.updateBlacklist(); // this.updateMalwarelist(); URLUtils urlutils = new URLUtils(); ArrayList<CheckURL> urls = urlutils.getLookupURLs(url); for (CheckURL checkURL : urls) { if (this.dao.locateBlacklistHash(checkURL.getMD5Hash()) || this.dao.locateMalwareHash(checkURL.getMD5Hash())) { return true; } } return false; } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngine#updateBlacklist() */ public void updateBlacklist() { if (this.dao != null) { try { HashMap<String, ListURL> data = this.session.getBlacklist(); if (this.session.isBlacklistUpdated()) { if (data.size() > 0) { } } else { if (data.size() > 0) { this.dao.replaceBlacklist(data, this.config); } } } catch (Exception e) { logger.log(Level.SEVERE, "Error while updating malware.", e); } } } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngine#updateMalwarelist() */ public void updateMalwarelist() { if (this.dao != null) { try { HashMap<String, ListURL> data = this.session.getMalwarelist(); if (this.session.isMalwareUpdated()) { if (data.size() > 0) { } } else { if (data.size() > 0) { this.dao.replaceMalwarelist(data, this.config); } } } catch (Exception e) { logger.log(Level.SEVERE, "Error while updating malware.", e); } } } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngine#registerDAO(uk.co.mccann.gsb.interfaces.GSBDAO) */ public void registerDAO(GSBDAO dao) { } /** * The Class AppEngineDAO. */ public static class AppEngineDAO implements GSBDAO { /** * Instantiates a new app engine dao. */ public AppEngineDAO() { } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBDAO#readBlacklist(uk.co.mccann.gsb.interfaces.GSBEngineConfiguration) */ @SuppressWarnings("unchecked") public HashMap<String, ListURL> readBlacklist(GSBEngineConfiguration config) { HashMap<String, ListURL> dataMap = new HashMap<String, ListURL>(); EntityManager entityManager = null; try { entityManager = EMF.get().createEntityManager(); Query query = entityManager.createNamedQuery(NamedQueries.FIND_ALL_BLACKLIST); List<Blacklist> result = query.getResultList(); for (Blacklist blacklist : result) { String hash = blacklist.getHash(); dataMap.put(hash, new ListURL(hash)); } } catch (Exception exp) { logger.log(Level.SEVERE, "Unable to read blacklist: ", exp); } finally { entityManager.close(); } return dataMap; } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBDAO#readMalwarelist(uk.co.mccann.gsb.interfaces.GSBEngineConfiguration) */ @SuppressWarnings("unchecked") public HashMap<String, ListURL> readMalwarelist(GSBEngineConfiguration config) { EntityManager entityManager = null; HashMap<String, ListURL> dataMap = new HashMap<String, ListURL>(); try { entityManager = EMF.get().createEntityManager(); Query query = entityManager.createNamedQuery(NamedQueries.FIND_ALL_MALWARE); List<Malware> result = query.getResultList(); for (Malware malware : result) { String hash = malware.getHash(); dataMap.put(hash, new ListURL(hash)); } } catch (Exception exp) { logger.log(Level.SEVERE, "Unable to read malware: ", exp); } finally { entityManager.close(); } return dataMap; } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBDAO#replaceBlacklist(java.util.HashMap, uk.co.mccann.gsb.interfaces.GSBEngineConfiguration) */ public void replaceBlacklist(HashMap<String, ListURL> list, GSBEngineConfiguration config) { EntityManager entityManager = null; try { entityManager = EMF.get().createEntityManager(); Query query = entityManager.createNamedQuery(NamedQueries.DELETE_ALL_BLACKLIST); query.executeUpdate(); ListURL url; for(String key : list.keySet()) { url = list.get(key); Blacklist blacklist = new Blacklist(); blacklist.setHash(url.getMD5Hash()); entityManager.persist(blacklist); } } catch (Exception exp) { logger.log(Level.SEVERE, "Unable to replace blacklist: ", exp); } finally { entityManager.close(); } } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBDAO#replaceMalwarelist(java.util.HashMap, uk.co.mccann.gsb.interfaces.GSBEngineConfiguration) */ public void replaceMalwarelist(HashMap<String, ListURL> list, GSBEngineConfiguration config) { EntityManager entityManager = null; try { entityManager = EMF.get().createEntityManager(); Query query = entityManager.createNamedQuery(NamedQueries.DELETE_ALL_MALWARE); query.executeUpdate(); ListURL url; for(String key : list.keySet()) { url = list.get(key); Malware malware = new Malware(); malware.setHash(url.getMD5Hash()); entityManager.persist(malware); } } catch (Exception exp) { logger.log(Level.SEVERE, "Unable to replace malware: ", exp); } finally { entityManager.close(); } } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBDAO#updateBlacklist(java.util.HashMap, uk.co.mccann.gsb.interfaces.GSBEngineConfiguration) */ public void updateBlacklist(HashMap<String, ListURL> list, GSBEngineConfiguration config) { EntityManager entityManager = null; try { entityManager = EMF.get().createEntityManager(); Query query = entityManager.createNamedQuery(NamedQueries.DELETE_BLACKLIST_BY_HASH); ListURL url; for(String key : list.keySet()) { url = list.get(key); if(url.isAdded()) { Blacklist blacklist = new Blacklist(); blacklist.setHash(url.getMD5Hash()); entityManager.persist(blacklist); } if(url.isRemoved()) { query.setParameter("hash", url.getMD5Hash()); query.executeUpdate(); } } } catch (Exception exp) { logger.log(Level.SEVERE, "Unable to update blacklist: ", exp); } finally { entityManager.close(); } } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBDAO#updateMalwarelist(java.util.HashMap, uk.co.mccann.gsb.interfaces.GSBEngineConfiguration) */ public void updateMalwarelist(HashMap<String, ListURL> list, GSBEngineConfiguration config) { EntityManager entityManager = null; try { entityManager = EMF.get().createEntityManager(); Query query = entityManager.createNamedQuery(NamedQueries.DELETE_MALWARE_BY_HASH); ListURL url; for(String key : list.keySet()) { url = list.get(key); if(url.isAdded()) { Malware malware = new Malware(); malware.setHash(url.getMD5Hash()); entityManager.persist(malware); } if(url.isRemoved()) { query.setParameter("hash", url.getMD5Hash()); query.executeUpdate(); } } } catch (Exception exp) { logger.log(Level.SEVERE, "Unable to update malware: ", exp); } finally { entityManager.close(); } } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBDAO#locateBlacklistHash(java.lang.String) */ public boolean locateBlacklistHash(String hashValue) { EntityManager entityManager = null; try { entityManager = EMF.get().createEntityManager(); Query query = entityManager.createNamedQuery(NamedQueries.FIND_BLACKLIST_BY_HASH); query.setParameter("hash", hashValue); Object result = query.getSingleResult(); if (result != null) { return true; } return false; } catch (Exception exp) { return false; } finally { entityManager.close(); } } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBDAO#locateMalwareHash(java.lang.String) */ public boolean locateMalwareHash(String hashValue) { EntityManager entityManager = null; try { entityManager = EMF.get().createEntityManager(); Query query = entityManager.createNamedQuery(NamedQueries.FIND_MALWARE_BY_HASH); query.setParameter("hash", hashValue); Object result = query.getSingleResult(); if (result != null) { return true; } return false; } catch (Exception exp) { return false; } finally { entityManager.close(); } } /** * Save properties. * * @param properties the properties */ public void saveProperties(Properties properties) { EntityManager entityManager = null; try { entityManager = EMF.get().createEntityManager(); Query query = entityManager.createNamedQuery(NamedQueries.FIND_CURRENT_VERSION); Version version = (Version) query.getSingleResult(); if (version != null) { version.setBlacklistMajorVersion(Long.parseLong(properties.getProperty("gsb.blacklist.version.major"))); version.setBlacklistMinorVersion(Long.parseLong(properties.getProperty("gsb.blacklist.version.minor"))); version.setMalwareMajorVersion(Long.parseLong(properties.getProperty("gsb.malware.version.major"))); version.setMalwareMinorVersion(Long.parseLong(properties.getProperty("gsb.malware.version.minor"))); } } catch (Exception exp) { logger.log(Level.SEVERE, "Unable to save version: ", exp); } finally { entityManager.close(); } } /** * Load properties. * * @param properties the properties */ public void loadProperties(Properties properties) { EntityManager entityManager = null; try { entityManager = EMF.get().createEntityManager(); Query query = entityManager.createNamedQuery(NamedQueries.FIND_CURRENT_VERSION); Version version = (Version) query.getSingleResult(); if (version != null) { properties.setProperty("gsb.blacklist.version.major", String.valueOf(version.getBlacklistMajorVersion())); properties.setProperty("gsb.blacklist.version.minor", String.valueOf(version.getBlacklistMinorVersion())); properties.setProperty("gsb.malware.version.major", String.valueOf(version.getMalwareMajorVersion())); properties.setProperty("gsb.malware.version.minor", String.valueOf(version.getMalwareMinorVersion())); } } catch (Exception exp) { logger.log(Level.SEVERE, "Unable to load version: ", exp); } finally { entityManager.close(); } } } /** * The Class AppEngineConfigImpl. */ public static class AppEngineConfigImpl implements GSBEngineConfiguration { /** The api key. */ private String apiKey; /** The use key. */ private boolean useKey; /** The properties file. */ private Properties propertiesFile; /** The dao. */ private AppEngineDAO dao; /** * Instantiates a new app engine config impl. * * @param dao the dao */ public AppEngineConfigImpl(AppEngineDAO dao) { this.dao = dao; this.propertiesFile = new Properties(); try { propertiesFile.load( GoogleSafeBrowsingGateway.class.getResourceAsStream("gsb.properties")); } catch (IOException e) { logger.log(Level.SEVERE, "An error occurred while loading properties.", e); } dao.loadProperties(this.propertiesFile); } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngineConfiguration#setAPIKey(java.lang.String) */ public void setAPIKey(String apikey) { this.apiKey = apikey; } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngineConfiguration#setPropertiesFile(java.lang.String) */ public void setPropertiesFile(String properties) { } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngineConfiguration#useKey(boolean) */ public void useKey(boolean useKey) { this.useKey = useKey; } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngineConfiguration#isUseKey() */ public boolean isUseKey() { if(this.useKey) return true; return false; } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngineConfiguration#getPropertiesFile() */ public Properties getPropertiesFile() { return this.propertiesFile; } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngineConfiguration#getAPIKey() */ public String getAPIKey() { return this.apiKey; } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngineConfiguration#savePropertiesFile() */ public void savePropertiesFile() throws IOException { dao.saveProperties(this.propertiesFile); } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngineConfiguration#getDataStoreDirectory() */ public String getDataStoreDirectory() { return null; } /* (non-Javadoc) * @see uk.co.mccann.gsb.interfaces.GSBEngineConfiguration#setDataStoreDirectory(java.lang.String) */ public void setDataStoreDirectory(String directory) { } } }