From c06c2d77925c02846d331a03c6071773facb1625 Mon Sep 17 00:00:00 2001 From: Patrick Neumann Date: Sun, 7 Apr 2019 20:45:14 +0200 Subject: [PATCH] =?UTF-8?q?=E2=80=9Eextract-and-index-evolution-mail-stora?= =?UTF-8?q?ge=E2=80=9C=20hinzuf=C3=BCgen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extract-and-index-evolution-mail-storage | 184 +++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 extract-and-index-evolution-mail-storage diff --git a/extract-and-index-evolution-mail-storage b/extract-and-index-evolution-mail-storage new file mode 100644 index 0000000..893bf3c --- /dev/null +++ b/extract-and-index-evolution-mail-storage @@ -0,0 +1,184 @@ +#!/usr/bin/env bash + +# Usage: ./extract-and-index-evolution-mail-storage +# or +# bash extract-and-index-evolution-mail-storage +# Description: (see scriptname!) +# Author: Patrick Neumann (patrick@neumannsland.de) +# Version: 0.9 +# Date: 07.04.2019 +# License: GPL3 +# Warranty: This program is distributed WITHOUT ANY WARRANTY +# Todo: - +# Tests: Linux Mint 19.1 + Evolution 3.28.5 + +#------------------------------------------------------------------------------- +# Simple checks for dependencies: +#------------------------------------------------------------------------------- +which ifind > /dev/null || ( echo "Please install sleuthkit!" ; exit 1 ) +which mu > /dev/null || ( echo "Please install mu!" ; exit 1 ) + +#=== FUNCTION ================================================================== +# NAME: usage +# DESCRIPTION: Display help. +# PARAMETERS: - +#=============================================================================== +usage () { + printf "Usage:\n" + printf " $0 \n" +} + +#------------------------------------------------------------------------------- +# Check for one param: +#------------------------------------------------------------------------------- +if [ "${#}" -ne 1 ]; then + echo "Please provide exactly one parameter!" + echo + usage + exit 2 +fi + +#=== CONFIGURATION (params) ==================================================== +#------------------------------------------------------------------------------- +# Check and set image: +#------------------------------------------------------------------------------- +if ! file "${1}" | grep -F "EWF" > /dev/null ; then + echo "Please provide EWF image!" + echo + usage + exit 3 +fi +readonly IMG="${1}" + +#=== CONFIGURATION (dynamic) =================================================== +#------------------------------------------------------------------------------- +# Find and set home directory: +#------------------------------------------------------------------------------- +offsets="$( mmls -aM "${IMG}" \ + | awk '/^[[:digit:]]{3}:/ { print $3; }' \ + | sed 's/0*//' )" +for offset in ${offsets} ; do + if fsstat -o "${offset}" "${IMG}" \ + | grep -E "^Last mounted on: /home$" > /dev/null + then + home="" + readonly S_PRE="" + readonly T_PRE="./recovered/home" + readonly OFS="${offset}" + elif fsstat -o "${offset}" "${IMG}" \ + | grep -E "^Last mounted on: /$" > /dev/null + then + home="$( ifind -o "${offset}" -n "/home" "${IMG}" )" + if [ "${home}" != "File not found" ] ; then + readonly S_PRE="/home" + readonly T_PRE="./recovered" + readonly OFS="${offset}" + fi + else + echo "/home not found!" + echo + echo "Hint:" + echo " 1.: assemble RAID and/or LVM" + echo " 2.: ewfacquire the file system of /home" + echo " 3.: use that image with ${0}" + exit 4 + fi +done + +#=== CONFIGURATION (user) ====================================================== +#------------------------------------------------------------------------------- +# Select user: +#------------------------------------------------------------------------------- +printf "Please select a user:\n" +users="$( fls -o "${OFS}" "${IMG}" "${home}" | awk '{ print $NF; }' )" +select user in ${users} ; do + if [ -n "${user}" ] ; then + break + fi +done + +#=== CONFIGURATION (static) ==================================================== +readonly LOCAL=".local/share/evolution/mail" +readonly CACHE=".cache/evolution/mail" +DIRS="${S_PRE}/${user}/${LOCAL}/" +readonly DIRS="${DIRS} ${S_PRE}/${user}/${CACHE}/" + +#------------------------------------------------------------------------------- +# ... magic ... +#------------------------------------------------------------------------------- +for DIR in ${DIRS} ; do + #----------------------------------------------------------------------------- + # Store inode of DIR as start: + #----------------------------------------------------------------------------- + start="$( ifind -o "${OFS}" -n "${DIR}" "${IMG}" )" + + if [ "${start}" = "File not found" ] ; then + echo "${DIR} not found!" + continue + fi + #----------------------------------------------------------------------------- + # Store directory paths recursively under start pipe separated as dirs: + #----------------------------------------------------------------------------- + dirs="$( fls -o "${OFS}" -u -D -r -m "${DIR}" "${IMG}" "${start}" )" + + #----------------------------------------------------------------------------- + # Create target folder structure recursively: + #----------------------------------------------------------------------------- + for dir in ${dirs} ; do + path="$( echo "${dir}" | cut -d "|" -f 2 )" + + # the subfolder between "cur" and the mail kill the RFC + if ! echo ${path} \ + | grep -E ".*/\.cache/evolution/mail/.*/folders/.*/cur/.*" > /dev/null + then + if ! [ -d "${path}" ] ; then + mkdir -p "${T_PRE}${path}" + fi + fi + done + + #----------------------------------------------------------------------------- + # Store file names recursively under start pipe separated as files: + #----------------------------------------------------------------------------- + files="$( fls -o "${OFS}" -u -F -r -m "${DIR}" "${IMG}" "${start}" )" + + #----------------------------------------------------------------------------- + # Extract files recursively into target folder(s): + #----------------------------------------------------------------------------- + for file in ${files} ; do + inode="$( echo "${file}" | cut -d "|" -f 3 )" + name="$( echo "${file}" | cut -d "|" -f 2 )" + + if ! echo ${name} \ + | grep -E ".*/\.cache/evolution/mail/.*/folders/.*/cur/.*/.*" > /dev/null + then + icat -o "${OFS}" "${IMG}" "${inode}" > "${T_PRE}${name}" + else + # replace the last slash with a hyphen + icat -o "${OFS}" "${IMG}" "${inode}" > "${T_PRE}${name%/*}-${name##*/}" + fi + done +done + +#------------------------------------------------------------------------------- +# Index the local mail storage: +#------------------------------------------------------------------------------- +if [ -d "${T_PRE}${S_PRE}/${user}/${LOCAL}" ] ; then + mu index --quiet --muhome=./mu --maildir="${T_PRE}${S_PRE}/${user}/${LOCAL}" +fi + +#------------------------------------------------------------------------------- +# Index the external mail storage(s): +#------------------------------------------------------------------------------- +accounts="$( find -E "${T_PRE}${S_PRE}/${user}/${CACHE}" -type d -depth 1 \ + -iregex ".*/[[:xdigit:]]{40}" -exec basename '{}' \; )" +for account in ${accounts} ; do + folders="$( find -E "${T_PRE}${S_PRE}/${user}/${CACHE}/${account}/folders" \ + -type d -depth 1 -exec basename '{}' \; )" + for folder in ${folders} ; do + mu index --quiet --muhome=./mu \ + --maildir="${T_PRE}${S_PRE}/${user}/${CACHE}/${account}/folders/${folder}" + done +done + +exit 0 \ No newline at end of file