package com.threatconnect.sdk.parser.util;
import com.threatconnect.sdk.parser.model.Address;
import com.threatconnect.sdk.parser.model.File;
import com.threatconnect.sdk.parser.model.Host;
import com.threatconnect.sdk.parser.model.Indicator;
import com.threatconnect.sdk.parser.model.Url;
import com.threatconnect.sdk.parser.service.bulk.InvalidIndicatorException;
import com.threatconnect.sdk.parser.util.regex.HostNameExtractor;
import com.threatconnect.sdk.parser.util.regex.MatchNotFoundException;
import java.util.regex.Matcher;
public class IndicatorUtil
{
private IndicatorUtil()
{
}
public static File createFile(final String summary) throws InvalidIndicatorException
{
//create a new file
File file = new File();
file.setMd5(extractHash(summary, File.MD5_LENGTH));
file.setSha1(extractHash(summary, File.SHA1_LENGTH));
file.setSha256(extractHash(summary, File.SHA256_LENGTH));
//make sure that one of the values was set
if (null == file.getMd5() && null == file.getSha1() && null == file.getSha256())
{
throw new InvalidIndicatorException("summary does not contain any valid hash codes");
}
return file;
}
private static String extractHash(final String text, final int hashLength)
{
//make sure the text is not null
if (null != text)
{
//split the text on the separator
String[] hashCodes = text.split(":");
//for each of the parts
for (String hash : hashCodes)
{
//check to see if this is the expected length
if (hash.trim().length() == hashLength)
{
//the hash was found
return hash.trim();
}
}
}
//no hashcode was found
return null;
}
/**
* Creates a URL indicator and ensures that the url is wellformed
*
* @param url the url to use
* @return a Url indicator object
* @throws InvalidURLException if the url is not valid
*/
public static Url createUrl(final String url) throws InvalidURLException
{
// make sure the url is not null or empty
if (null != url && !url.trim().isEmpty())
{
String fullUrl;
if (!UrlUtil.isAbsoluteURL(url.trim()))
{
fullUrl = "http://" + url.trim();
}
else
{
fullUrl = url.trim();
}
Url result = new Url();
result.setText(fullUrl);
return result;
}
else
{
throw new InvalidURLException("url cannot be null or empty");
}
}
/**
* Given a URL, this extracts either the hostname or the ipaddress of the url and returns the
* indicator with the appropriate field populated
*
* @param url the url string to use
* @return the indicator that was created
* @throws MatchNotFoundException if the url could not be identified as an indicator
*/
public static Indicator extractHostOrAddress(final String url) throws MatchNotFoundException
{
// retrieve the hostname of the url
String ipAddressOrHostName = new HostNameExtractor(url.trim()).getHostName();
return createHostOrAddress(ipAddressOrHostName);
}
/**
* Given a hostname or an ip address, an appropriate indicator is created
*
* @param ipAddressOrHostName the text to use
* @return the indicator that was created
*/
public static Indicator createHostOrAddress(final String ipAddressOrHostName)
{
// check to see if this is an IP address
if (RegexUtil.REGEX_IP_FORMAT.matcher(ipAddressOrHostName.trim()).matches())
{
// create an address indicator
Address address = new Address();
address.setIp(cleanIP(ipAddressOrHostName.trim()));
return address;
}
else
{
// create a host indicator
Host host = new Host();
host.setHostName(ipAddressOrHostName.trim());
return host;
}
}
/**
* Cleans an IP address
* <p>
* 1. Strips all leading 0s that are not necessary
* </p>
*
* @param ip the ip address to clean up
* @return the clean ip address
*/
public static String cleanIP(final String ip)
{
// create a matcher for this ip
Matcher matcher = RegexUtil.REGEX_LEADING_ZEROS.matcher(ip.trim());
// check to see if there are any matches
if (matcher.find())
{
// remove all of the leading zeros and recursively call this again to ensure that the ip
// is now clean
return cleanIP(ip.trim().replaceAll(RegexUtil.REGEX_LEADING_ZEROS.pattern(), ""));
}
else
{
// the ip address is good
return ip.trim();
}
}
}