1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
/*
** The Sleuth Kit
**
** Brian Carrier [carrier <at> sleuthkit [dot] org]
** Copyright (c) 2010-2019 Brian Carrier. All Rights reserved
**
** This software is distributed under the Common Public License 1.0
**
*/
#include <string>
#include <algorithm>
#include <regex>
#include "LogicalImagerPathRule.h"
#include "TskHelper.h"
/* case insensitive user folder prefixes */
static char *userFolderRegex = "/?(documents and settings|users|home)/[^/]+";
static std::string lowerCaseUserFolder;
/*
* Construct a path rule.
*
* @param paths A set of path strings. The path should not contain any filename.
* The path is case-insensitive. It it normalize to lowercase.
* A path starting with the "[USER_FOLDER]" special string will match any user folder prefix.
* For example: "[USER_FOLDER]/Downloads" will match all Downloads folder under the user folder.
* Microsoft Windows Vista, 7, 8 and 10 - /Users/john/Downloads
* Microsoft Windows 2000, XP and 2003- /Documents and Settings/john/Downloads
* Linux - /home/john/Downloads
* macOS - /Users/john/Downloads
*/
LogicalImagerPathRule::LogicalImagerPathRule(const std::set<std::string> &paths) {
lowerCaseUserFolder = TskHelper::toLower(getUserFolder());
for (auto it = std::begin(paths); it != std::end(paths); ++it) {
validatePath(*it);
std::string lowerCasePath = TskHelper::toLower(*it);
if (lowerCasePath.size() >= lowerCaseUserFolder.size() &&
lowerCasePath.compare(0, lowerCaseUserFolder.size(), lowerCaseUserFolder) == 0) {
// [USER_FOLDER] must be at the start of path
// special case, add to regex
std::string newPattern(lowerCasePath);
newPattern.replace(newPattern.find(lowerCaseUserFolder), lowerCaseUserFolder.length(), userFolderRegex);
if (TskHelper::endsWith(lowerCasePath, "/")) {
newPattern.append(".*");
} else {
newPattern.append("/.*");
}
std::regex pattern(newPattern);
m_userFolderRegexes.push_back(pattern);
} else {
m_paths.insert(TskHelper::toLower(*it));
}
}
}
LogicalImagerPathRule::~LogicalImagerPathRule() {
m_paths.clear();
m_userFolderRegexes.clear();
}
/**
* Match all user folder paths using regex_match
* @param rule Rule specified containing [USER_FOLDER] string
* @param path Path to be matched
* @returns true if there is a match, false otherwise
*/
bool LogicalImagerPathRule::matchUserFolder(const std::string path) const {
for (auto it = std::begin(m_userFolderRegexes); it != std::end(m_userFolderRegexes); ++it) {
if (std::regex_match(path, *it)) {
return true;
}
}
return false;
}
/**
* Match a file's path against the logical imager path set
*
* @param fs_file TSK_FS_FILE containing the filename
* @param path parent path to fs_file
* @returns true if the path matches this rule
* false otherwise
*/
bool LogicalImagerPathRule::matches(TSK_FS_FILE * /*fs_file*/, const char *path) const {
if (path == NULL)
return false;
const std::string lowercasePath = TskHelper::toLower(path);
if (matchUserFolder(lowercasePath)) {
return true;
}
for (auto it = std::begin(m_paths); it != std::end(m_paths); ++it) {
if (lowercasePath.find(*it) != std::string::npos) {
return true;
}
}
return false;
}
|