package com.mesasoft.cn.sketch.util; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.log.Log; import com.mesasoft.cn.sketch.config.AppConfig; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import sun.net.util.IPAddressUtil; import javax.annotation.Resource; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ValidationUtils { private static final Log logger = Log.get(); private static String tldFilePath; // @Value("${sketch.tld.file}") // public void setTldFilePath(String ttlFilePath) { // this.tldFilePath = ttlFilePath; // if (StringUtils.isBlank(ttlFilePath) || !FileUtil.exist(ttlFilePath)) { // this.tldFilePath = ResourceUtil.getResource("public_suffix_list_only.dat").getPath(); // } // } static { tldFilePath = ResourceUtil.getResource("public_suffix_list_only.dat").getPath(); } /** * 获取二级域名 **/ public static String getSecDomain(String fqdnOrUrl) { HashMap> maps = readTopDomainFile(tldFilePath); try { String[] split = fqdnOrUrl.split("\\."); String secDomain = null; for (int i = split.length - 1; i >= 0; i--) { int maps_index = split.length - (i + 1); HashMap innerMap = maps.get("map_id_" + maps_index); HashMap fullTop = maps.get("full"); if (!(innerMap.containsKey(split[i]))) { String strSec = ""; for (int j = i; j < split.length; j++) { strSec += (split[j] + "."); } secDomain = strSec.substring(0, strSec.length() - 1); if (fullTop.containsKey(getTopFromSecDomain(secDomain))) { break; } else { while (!fullTop.containsKey(getTopFromSecDomain(secDomain)) && getTopFromSecDomain(secDomain).contains(".")) { secDomain = getTopFromSecDomain(secDomain); } break; } } } // 右匹配为顶级域名 if (secDomain == null) { secDomain = fqdnOrUrl; } return secDomain; } catch (Exception e) { logger.error("urlDomain:" + fqdnOrUrl); return "---no---return---"; } } public static List getSecDomain(List fqdnOrUrls) { HashMap> maps = readTopDomainFile(tldFilePath); List secDomainList = new ArrayList<>(); for (String oriDomain : fqdnOrUrls) { String secDomain = getSecDomain(oriDomain); if (StringUtils.isNotBlank(secDomain) && !("---no---return---".equals(secDomain))) { secDomainList.add(secDomain); } else { logger.info(oriDomain); } } return secDomainList; } public static String getTopFromSecDomain(String secDomain) { String quFirstDian = secDomain; if (secDomain.contains(".")) { quFirstDian = secDomain.substring(secDomain.indexOf(".")).substring(1); } return quFirstDian; } public static HashMap> readTopDomainFile(String filePath) { HashMap> maps = makeHashMap(filePath); try { String encoding = "UTF-8"; File file = new File(filePath); if (file.isFile() && file.exists()) { InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding); BufferedReader bufferedReader = new BufferedReader(read); String lineTxt = null; while ((lineTxt = bufferedReader.readLine()) != null) { HashMap fullTop = maps.get("full"); fullTop.put(lineTxt, lineTxt); maps.put("full", fullTop); String[] split = lineTxt.split("\\."); for (int i = split.length - 1; i >= 0; i--) { int maps_index = split.length - (i + 1); HashMap innerMap = maps.get("map_id_" + maps_index); innerMap.put(split[i], split[i]); maps.put("map_id_" + maps_index, innerMap); } } read.close(); } else { logger.error("TopDomainUtils>=>readTopDomainFile filePath is wrong--->{" + filePath + "}<---"); } } catch (Exception e) { logger.error("TopDomainUtils>=>readTopDomainFile get filePathData error--->{" + e + "}<---"); } return maps; } public static HashMap> makeHashMap(String filePath) { int maxLength = FileUtils.getMaxLength(filePath); HashMap> maps = new HashMap>(); for (int i = 0; i < maxLength; i++) { maps.put("map_id_" + i, new HashMap()); } maps.put("full", new HashMap()); return maps; } public static List getChecked(List objectList, String type) { if (type.equals("ip")) { return getCheckedIps(objectList); } if (type.equals("domain")) { return getCheckedFqdns(objectList); } logger.error("Wrong type to be checked: " + type); return objectList; } public static List getCheckedFqdns(List fqdns) { List res = new ArrayList<>(); for (String fqdn : fqdns) { //去端口号 fqdn = fqdn.split(":")[0]; // 去重 & 校验 if (isValidDomain(fqdn) && !res.contains(fqdn)) { res.add(fqdn.toLowerCase()); } else { logger.debug("Bad or duplicated fqdn:" + fqdn); } } return res; } public static List getCheckedIps(List ipList) { List res = new ArrayList<>(); for (String ip : ipList) { //去端口号 ip = ip.split(":")[0]; // 去重 & 校验 if (isValidIp(ip) && !res.contains(ip)) { res.add(ip.toLowerCase()); } else { logger.debug("Bad or duplicated fqdn:" + ip); } } return res; } public static boolean isValidIp(String ip) { boolean iPv4LiteralAddress = IPAddressUtil.isIPv4LiteralAddress(ip); boolean iPv6LiteralAddress = IPAddressUtil.isIPv6LiteralAddress(ip); return iPv4LiteralAddress || iPv6LiteralAddress; } private static boolean isValidDomain(String str) { String regex = "^((?!-)[A-Za-z0-9-_]" + "{1,63}(?