Sleuth Kit Java Bindings (JNI) 4.14.0
Java bindings for using The Sleuth Kit
Loading...
Searching...
No Matches
MessageAttachments.java
Go to the documentation of this file.
1/*
2 * Sleuth Kit Data Model
3 *
4 * Copyright 2019-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.datamodel.blackboardutils.attributes;
20
21import com.google.common.collect.ImmutableList;
22import java.util.ArrayList;
23import java.util.Collection;
24import java.util.Collections;
25import java.util.List;
26import org.sleuthkit.datamodel.AbstractFile;
27import org.sleuthkit.datamodel.Content;
28import org.sleuthkit.datamodel.DerivedFile;
29import org.sleuthkit.datamodel.SleuthkitCase;
30import org.sleuthkit.datamodel.TskCoreException;
31import org.sleuthkit.datamodel.TskData;
32
39public final class MessageAttachments {
40
45 public interface Attachment {
46
52 String getLocation();
53
54 /*
55 * Returns object id of the attachment file.
56 *
57 * @return Object id of attachment, may be null if not available or not
58 * applicable.
59 */
60 Long getObjId();
61
62 }
63
69 public static class URLAttachment implements Attachment {
70
71 private final String url;
72
78 public URLAttachment(String url) {
79 this.url = url;
80 }
81
87 public String getURL() {
88 return url;
89 }
90
91 @Override
92 public String getLocation() {
93 return this.url;
94 }
95
96 @Override
97 public Long getObjId() {
98 // no real object available.
99 return null;
100 }
101
102 }
103
114 public static final class FileAttachment implements Attachment {
115
116 private final String path;
117 private final long objectID;
118
119 // Mobile phones often create mount points to refer to SD Cards or other
120 // fixed/removable storage media.
121 //
122 // Applications use these mount points when referring files. But they may
123 // not exist physically in the data source.
124 //
125 // Common, wellknown mount points are stripped from the file paths to
126 // accurately search for the file in the image.
127 transient private static final List<String> KNOWN_MOUNTPOINTS
128 = ImmutableList.of(
129 "/data/", // NON-NLS
130 "/storage/emulated/"); //NON-NLS
131
146 public FileAttachment(SleuthkitCase caseDb, Content dataSource, String pathName) throws TskCoreException {
147
148 //normalize the slashes.
149 this.path = normalizePath(pathName);
150
151 String fileName = path.substring(path.lastIndexOf('/') + 1);
152 if (fileName.isEmpty()) {
153 throw new TskCoreException(String.format("No file name specified for attachment file: %s, on data source = %d", path, dataSource.getId()));
154 }
155
156 String parentPathSubString = (path.lastIndexOf('/') < 0) ? "" : path.substring(0, path.lastIndexOf('/'));
157
158 // find the attachment file
159 objectID = findAttachmentFile(caseDb, fileName, parentPathSubString, dataSource);
160 }
161
174 public FileAttachment(DerivedFile derivedFile) throws TskCoreException {
175 objectID = derivedFile.getId();
176 path = derivedFile.getUniquePath();
177 }
178
184 public FileAttachment(AbstractFile abstractFile) {
185 objectID = abstractFile.getId();
186 path = abstractFile.getParentPath() + "/" + abstractFile.getName();
187 }
188
194 public String getPathName() {
195 return path;
196 }
197
204 public long getObjectId() {
205 return objectID;
206 }
207
216 private String normalizePath(String path) {
217 //normalize the slashes, replace encoded space
218 String adjustedPath = path.replace("\\", "/").replace("%20", " ");
219
220 // Strip common known mountpoints.
221 for (String mountPoint : KNOWN_MOUNTPOINTS) {
222 if (adjustedPath.toLowerCase().startsWith(mountPoint)) {
223 adjustedPath = ("/").concat(adjustedPath.substring(mountPoint.length()));
224 break;
225 }
226 }
227
228 return adjustedPath;
229 }
230
246 private long findAttachmentFile(SleuthkitCase caseDb, String fileName, String parentPathSubstring, Content dataSource) throws TskCoreException {
247
248 // Find all files with matching name and parent path substring
249 String whereClause = String.format("LOWER(name) = LOWER('%s') AND LOWER(parent_path) LIKE LOWER('%%%s%%')", fileName, parentPathSubstring);
250 List<AbstractFile> matchedFiles = caseDb.findAllFilesWhere(whereClause);
251
252 // separate the matching files into allocated files on same datsource,
253 // allocated files on other data sources, and unallocated files.
254 List<Long> allocFileMatchesOnSameDatasource = new ArrayList<>();
255 List<Long> allocFileMatchesOnOtherDatasources = new ArrayList<>();
256 List<Long> unallocFileMatches = new ArrayList<>();
257
258 for (AbstractFile file : matchedFiles) {
259 if (file.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC)) {
260 if (dataSource.getId() == file.getDataSource().getId()) {
261 allocFileMatchesOnSameDatasource.add(file.getId());
262 } else {
263 allocFileMatchesOnOtherDatasources.add(file.getId());
264 }
265 } else { // unallocated file
266 unallocFileMatches.add(file.getId());
267 }
268 }
269
270 // pick the best match from the 3 lists.
271 return pickBestMatchFile(allocFileMatchesOnSameDatasource, allocFileMatchesOnOtherDatasources, unallocFileMatches);
272 }
273
302 private long pickBestMatchFile(List<Long> allocFileMatchesOnSameDatasource,
303 List<Long> allocFileMatchesOnOtherDatasources,
304 List<Long> unallocFileMatches) {
305
306 // check if there's an allocated file match on the same data source
307 if (!allocFileMatchesOnSameDatasource.isEmpty() && allocFileMatchesOnSameDatasource.size() == 1) {
308 return allocFileMatchesOnSameDatasource.get(0);
309 }
310 // if no match found yet,check if there's an allocated file match on other data sources.
311 if (!allocFileMatchesOnOtherDatasources.isEmpty()
312 && allocFileMatchesOnOtherDatasources.size() == 1) {
313 return allocFileMatchesOnOtherDatasources.get(0);
314 }
315 // if no match found yet, check if there is an unallocated file that matches.
316 if (!unallocFileMatches.isEmpty()
317 && unallocFileMatches.size() == 1) {
318 return unallocFileMatches.get(0);
319 }
320 // no single suitable match found
321 return -1;
322
323 }
324
325 @Override
326 public String getLocation() {
327 return this.path;
328 }
329
330 @Override
331 public Long getObjId() {
332 return this.objectID;
333 }
334 }
335
336 private final Collection<FileAttachment> fileAttachments;
337 private final Collection<URLAttachment> urlAttachments;
338
346 public MessageAttachments(Collection<FileAttachment> fileAttachments, Collection<URLAttachment> urlAttachments) {
347 this.fileAttachments = fileAttachments;
348 this.urlAttachments = urlAttachments;
349 }
350
356 public Collection<FileAttachment> getFileAttachments() {
357 return Collections.unmodifiableCollection(fileAttachments);
358 }
359
365 public Collection<URLAttachment> getUrlAttachments() {
366 return Collections.unmodifiableCollection(urlAttachments);
367 }
368
374 public int getAttachmentsCount() {
375 return (fileAttachments.size() + urlAttachments.size());
376 }
377}
FileAttachment(SleuthkitCase caseDb, Content dataSource, String pathName)
MessageAttachments(Collection< FileAttachment > fileAttachments, Collection< URLAttachment > urlAttachments)
ALLOC
Metadata structure is currently in an allocated state.
Definition TskData.java:208

Copyright © 2011-2024 Brian Carrier. (carrier -at- sleuthkit -dot- org)
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.