Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
DefaultDomainCategorizer.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2020 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package org.sleuthkit.autopsy.recentactivity;
20
21import java.io.BufferedReader;
22import java.io.IOException;
23import java.io.InputStream;
24import java.io.InputStreamReader;
25import java.nio.charset.StandardCharsets;
26import java.util.Arrays;
27import java.util.HashMap;
28import java.util.List;
29import java.util.Map;
30import java.util.logging.Level;
31import org.apache.commons.lang.StringUtils;
32import org.sleuthkit.autopsy.coreutils.Logger;
33import org.sleuthkit.autopsy.url.analytics.DomainCategorizer;
34import org.sleuthkit.autopsy.url.analytics.DomainCategorizerException;
35import org.sleuthkit.autopsy.url.analytics.DomainCategory;
36
56@SuppressWarnings("try")
58
59 private static final String COMMENT_PREFIX = "#";
60 private static final String CSV_DELIMITER = ",";
61 private static final String DOMAIN_TYPE_CSV = "default_domain_categories.csv"; //NON-NLS
62 private static final Logger logger = Logger.getLogger(DefaultDomainCategorizer.class.getName());
63
71 private static Map<String, String> loadMapping() throws IOException {
72 try (InputStream is = DomainCategoryRunner.class.getResourceAsStream(DOMAIN_TYPE_CSV);
73 InputStreamReader isReader = new InputStreamReader(is, StandardCharsets.UTF_8);
74 BufferedReader reader = new BufferedReader(isReader)) {
75
76 Map<String, String> mapping = new HashMap<>();
77 int lineNum = 1;
78 while (reader.ready()) {
79 String line = reader.readLine();
80 if (!StringUtils.isBlank(line) && !line.startsWith(COMMENT_PREFIX)) {
81 addItem(mapping, line.trim(), lineNum);
82 lineNum++;
83 }
84 }
85
86 return mapping;
87 }
88 }
89
98 private static void addItem(Map<String, String> mapping, String line, int lineNumber) {
99 // make sure this isn't a blank line.
100 if (StringUtils.isBlank(line)) {
101 return;
102 }
103
104 String[] csvItems = line.split(CSV_DELIMITER);
105 // line should be a key value pair
106 if (csvItems.length < 2) {
107 logger.log(Level.WARNING, String.format("Unable to properly parse line of \"%s\" at line %d", line, lineNumber));
108 return;
109 }
110
111 // determine the domain type from the value, and return if can't be determined.
112 String domainTypeStr = csvItems[1].trim();
113 if (StringUtils.isBlank(domainTypeStr)) {
114 logger.log(Level.WARNING, String.format("No category specified for this line: \"%s\" at line %d", line, lineNumber));
115 return;
116 }
117
118 // determine the host
119 String hostSuffix = csvItems[0];
120 if (StringUtils.isBlank(hostSuffix)) {
121 logger.log(Level.WARNING, String.format("Could not determine host suffix for this line: \"%s\" at line %d", line, lineNumber));
122 return;
123 }
124
125 mapping.put(hostSuffix.toLowerCase(), domainTypeStr);
126 }
127
128 // the host suffix to category mapping.
129 private Map<String, String> mapping = null;
130
131 @Override
132 public synchronized void initialize() throws DomainCategorizerException {
133 if (isInitialized()) {
134 return;
135 }
136
137 try {
138 this.mapping = loadMapping();
139 } catch (IOException ex) {
140 throw new DomainCategorizerException("Unable to load domain type csv for domain category analysis", ex);
141 }
142 }
143
149 private synchronized boolean isInitialized() {
150 return this.mapping != null;
151 }
152
153 @Override
154 public synchronized DomainCategory getCategory(String domain, String host) throws DomainCategorizerException {
155 if (!isInitialized()) {
156 initialize();
157 }
158
159 // use host; use domain as fallback if no host provided
160 String hostToUse = StringUtils.isBlank(host) ? domain : host;
161
162 if (StringUtils.isBlank(hostToUse)) {
163 return null;
164 }
165
166 // split the host into tokens and find longest matching suffix
167 // (or return null if not found)
168 List<String> tokens = Arrays.asList(hostToUse.split("\\."));
169 for (int i = 0; i < tokens.size(); i++) {
170 String searchString = String.join(".", tokens.subList(i, tokens.size()));
171 String category = mapping.get(searchString);
172 if (StringUtils.isNotBlank(category)) {
173 return new DomainCategory(searchString, category);
174 }
175 }
176
177 return null;
178 }
179
180 @Override
181 public synchronized void close() throws Exception {
182 // clear out the mapping to release resources
183 mapping = null;
184 }
185}
synchronized static Logger getLogger(String name)
Definition Logger.java:124
static void addItem(Map< String, String > mapping, String line, int lineNumber)
synchronized DomainCategory getCategory(String domain, String host)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.