# # $Date: 2006/05/03 22:12:57 $ # # Notes and sequencer functions # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package Notes; use POSIX; $Notes::ENTER_FILE = 1; $Notes::ENTER_DATA = 2; $Notes::WRITE_FILE = 3; $Notes::WRITE_DATA = 4; $Notes::WRITE_SEQ_MAN = 5; $Notes::READ_NORM = 6; $Notes::READ_SEQ = 7; sub main { # There is no default for Notes Args::check_view(); Print::print_check_error("Notes option is not enabled") if ($::USE_NOTES == 0); my $view = Args::get_view(); if ($view == $Notes::ENTER_FILE) { return enter_file(); } elsif ($view == $Notes::ENTER_DATA) { return enter_data(); } elsif ($view == $Notes::WRITE_FILE) { return write_file(); } elsif ($view == $Notes::WRITE_DATA) { return write_data(); } elsif ($view == $Notes::WRITE_SEQ_MAN) { return write_seq_man(); } elsif ($view == $Notes::READ_NORM) { return read_norm(); } elsif ($view == $Notes::READ_SEQ) { return read_seq(); } else { Print::print_check_err("Invalid Notes View"); } } sub investig_notes_fname { return "$::host_dir" . "$::LOGDIR/$Args::args{'inv'}.notes"; } sub investig_seq_notes_fname { return "$::host_dir" . "$::LOGDIR/$Args::args{'inv'}.seq.notes"; } # window where user can enter a normal and sequencer note for a file # or meta data structure. sub enter_file { Args::check_vol('vol'); Args::check_meta('meta'); my $vol = Args::get_vol('vol'); my $ftype = $Caseman::vol2ftype{$vol}; my $mnt = $Caseman::vol2mnt{$vol}; my $meta = Args::get_meta('meta'); # A file will have a 'dir' argument and a meta structure will not if (exists $Args::args{'dir'}) { my $fname = "$mnt$Args::args{'dir'}"; Print::print_html_header("Notes for file $fname"); print "
\n\n";
# Date
my $tmp = localtime();
print NOTES "$tmp\n";
print "$tmp
\n";
print NOTES "Volume: $vol $Fs::addr_unit{$ftype}: $block Len: $len\n";
print "Volume: $vol $Fs::addr_unit{$ftype}: $block Len: $len
\n";
# The actual notes and a line at the bottom
print NOTES "\n$Args::args{'note'}\n\n" . "-" x 70 . "\n";
print "
$Args::args{'note'}
"; close(NOTES); print "
"
. ""
. "\n";
Print::print_html_footer();
return 0;
}
sub write_file {
Args::check_vol('vol');
Args::check_meta('meta');
Args::check_note();
# Get rid of carriage returns that Netscape adds
$Args::args{'note'} =~ tr/\r//d;
my $vol = Args::get_vol('vol');
my $mnt = $Caseman::vol2mnt{$vol};
my $ftype = $Caseman::vol2ftype{$vol};
my $img_sh = $Caseman::vol2sname{$vol};
my $meta = Args::get_meta('meta');
my $img = $Caseman::vol2path{$vol};
my $offset = $Caseman::vol2start{$vol};
my $imgtype = $Caseman::vol2itype{$vol};
my $fname = "";
my $type = "";
if (exists $Args::args{'dir'}) {
$Args::args{'dir'} .= "/"
if ($Args::args{'dir'} eq "");
$fname = "$mnt$Args::args{'dir'}";
if (($Args::args{'dir'} =~ /\/$/) || ($Args::args{'dir'} eq "")) {
Print::log_host_inv(
"$img_sh: Creating note for directory $fname ($meta)");
$type = "dir";
}
else {
Print::log_host_inv(
"$img_sh: Creating note for file $fname ($meta)");
$type = "file";
}
}
else {
Print::log_host_inv(
"$img_sh: Creating note for $Fs::meta_str{$ftype} $meta");
$type = "$Fs::meta_str{$ftype}";
}
Print::print_html_header("Writing a note / event");
# Get the times for the meta
# Set the timezone to the host zone
if ("$Caseman::tz" ne "") {
$ENV{TZ} = "$Caseman::tz";
POSIX::tzset();
}
my $meta_int = $meta;
$meta_int = $1 if ($meta_int =~ /^(\d+)-\d+(-\d+)?$/);
local *OUT;
Exec::exec_pipe(*OUT,
"'$::TSKDIR/ils' -f $ftype -e -o $offset -i $imgtype $img $meta_int");
# Skip to the fourth line
my $tmp = Exec::read_pipe_line(*OUT);
$tmp = Exec::read_pipe_line(*OUT);
$tmp = Exec::read_pipe_line(*OUT);
$tmp = Exec::read_pipe_line(*OUT);
unless ((defined $tmp)
&& ($tmp =~ /^$::REG_META\|\w\|\d+\|\d+\|(\d+)\|(\d+)\|(\d+)\|/o))
{
Print::print_err("Error parsing 'ils' output
");
}
my $mtime = $1;
my $atime = $2;
my $ctime = $3;
close(OUT);
# Create a "normal" note
if ((exists $Args::args{'norm_note'}) && ($Args::args{'norm_note'} == 1)) {
my $notes_file = investig_notes_fname();
open NOTES, ">>$notes_file" or die "Can't open log: $notes_file";
print "Note added to $notes_file:
\n\n";
# Date
my $tmp = localtime();
print NOTES "$tmp\n";
print "$tmp\n";
# We have a file name
if ($fname ne "") {
if ($type eq 'dir') {
print NOTES "Directory: $fname\n";
print "Directory: $fname
\n";
}
else {
print NOTES "File: $fname\n";
print "File: $fname
\n";
}
}
if ($meta ne "") {
print NOTES "Volume: $vol Meta: $meta\n";
print "Volume: $vol Meta: $meta
\n";
}
print NOTES "M-time: " . localtime($mtime) . "\n";
print "M-time: " . localtime($mtime) . "
\n";
print NOTES "A-time: " . localtime($atime) . "\n";
print "A-time: " . localtime($atime) . "
\n";
print NOTES "C-time: " . localtime($ctime) . "\n";
print "C-time: " . localtime($ctime) . "
\n";
# The actual notes and a line at the bottom
print NOTES "\n$Args::args{'note'}\n\n" . "-" x 70 . "\n";
print "
$Args::args{'note'}
"; close(NOTES); } # Create a sequencer event - if there are any unless (((exists $Args::args{'mtime'}) && ($Args::args{'mtime'} == 1)) || ((exists $Args::args{'atime'}) && ($Args::args{'atime'} == 1)) || ((exists $Args::args{'ctime'}) && ($Args::args{'ctime'} == 1))) { print "
"
. ""
. "\n";
Print::print_html_footer();
return 0;
}
# Get rid of the carriage returns
$Args::args{'note'} =~ s/\n/
/gs;
my $notes_file = investig_seq_notes_fname();
open NOTES, ">>$notes_file" or die "Can't open log: $notes_file";
if ((exists $Args::args{'mtime'}) && ($Args::args{'mtime'} == 1)) {
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
localtime($mtime);
$year += 1900;
$mon += 1;
$mday = "0$mday" if ($mday < 10);
$hour = "0$hour" if ($hour < 10);
$min = "0$min" if ($min < 10);
$sec = "0$sec" if ($sec < 10);
print NOTES "'$year','$mon','$mday','$hour','$min','$sec',"
. "'$Args::args{'host'}','$vol','$fname','$meta','',"
. "'$type','[M-Time]$Args::args{'note'}'\n";
Print::log_host_inv(
"$img_sh: M-Time note added for meta $Args::args{'meta'}");
print "M-Time sequence event added
\n";
}
if ((exists $Args::args{'atime'}) && ($Args::args{'atime'} == 1)) {
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
localtime($atime);
$year += 1900;
$mon += 1;
$mday = "0$mday" if ($mday < 10);
$hour = "0$hour" if ($hour < 10);
$min = "0$min" if ($min < 10);
$sec = "0$sec" if ($sec < 10);
print NOTES "'$year','$mon','$mday','$hour','$min','$sec',"
. "'$Args::args{'host'}','$vol','$fname','$meta','',"
. "'$type','[A-Time]$Args::args{'note'}'\n";
Print::log_host_inv(
"$img_sh: A-Time note added for meta $Args::args{'meta'}");
print "A-Time sequence event added
\n";
}
if ((exists $Args::args{'ctime'}) && ($Args::args{'ctime'} == 1)) {
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
localtime($ctime);
$year += 1900;
$mon += 1;
$mday = "0$mday" if ($mday < 10);
$hour = "0$hour" if ($hour < 10);
$min = "0$min" if ($min < 10);
$sec = "0$sec" if ($sec < 10);
print NOTES "'$year','$mon','$mday','$hour','$min','$sec',"
. "'$Args::args{'host'}','$vol','$fname','$meta','',"
. "'$type','[C-Time]$Args::args{'note'}'\n";
Print::log_host_inv(
"$img_sh: C-Time note added for meta $Args::args{'meta'}");
print "C-Time sequence event added
\n";
}
close(NOTES);
print "
";
if ((exists $Args::args{'norm_note'}) && ($Args::args{'norm_note'} == 1)) {
print
""
. "\n";
}
print
""
. "
\n";
Print::print_html_footer();
return 0;
}
# Display the contents of the "normal" notes file
sub read_norm {
Print::print_html_header("Contents of Notes File");
my $notes_file = investig_notes_fname();
Print::log_host_inv("Viewing contents of notes file ($notes_file)");
if ((!(-e "$notes_file")) || (-z "$notes_file")) {
print "No notes have been entered yet.
\n"
. "They can be entered using the Add Note link within each analysis mode.
\n";
return;
}
open NOTES, "<$notes_file" or die "Can't open log: $notes_file";
my $file = "";
my $dir = "";
print "
\n";
my $row = 0;
# This will need to change whenever the log format changes
while ( |
\n"; } else { print " |
\n";
}
}
else {
print "$_ "; } if (/^Volume: ($::REG_VNAME) Meta: ([0-9\-]+)/o) { $vol = $1; $meta = $2; next unless (exists $Caseman::vol2cat{$vol}); # file note if ($file ne "") { # extract the prepended mnt value my $mnt = $Caseman::vol2mnt{$vol}; my $fname = ""; $fname = $1 if ($file =~ /^$mnt\/?(.*)$/); print "" . " ![]() \n"; } # directory note elsif ($dir ne "") { # extract the prepended mnt value my $mnt = $Caseman::vol2mnt{$vol}; my $fname = ""; $fname = $1 if ($dir =~ /^$mnt\/?(.*)$/); print "" . " ![]() \n"; } # meta note else { print "" . " ![]() \n"; } } # block note elsif (/^Volume: ($::REG_VNAME) \w+: ([0-9]+) Len: (\d+)/o) { $vol = $1; $blk = $2; $len = $3; next unless (exists $Caseman::vol2cat{$vol}); print "" . " ![]() \n"; } } print " |
\n"
. ""
. "![]() | \n"
. ""
. "![]() |
"
. "");
}
# Check the args and add them to the final string that will be written
my $str = "";
unless ((exists $Args::args{'year'})
&& ($Args::args{'year'} =~ /^(\d\d\d\d)$/))
{
Print::print_err("Invalid year
");
}
$str .= "'$1',";
unless ((exists $Args::args{'mon'}) && ($Args::args{'mon'} =~ /^(\d\d?)$/))
{
Print::print_err("Invalid month
");
}
$str .= "'$1',";
unless ((exists $Args::args{'day'}) && ($Args::args{'day'} =~ /^(\d\d?)$/))
{
Print::print_err("Invalid day
");
}
$str .= "'$1',";
unless ((exists $Args::args{'hour'})
&& ($Args::args{'hour'} =~ /^(\d\d?)$/))
{
Print::print_err("Invalid hour
");
}
$str .= "'$1',";
unless ((exists $Args::args{'min'}) && ($Args::args{'min'} =~ /^(\d\d?)$/))
{
Print::print_err("Invalid min
");
}
$str .= "'$1',";
unless ((exists $Args::args{'sec'}) && ($Args::args{'sec'} =~ /^(\d\d?)$/))
{
Print::print_err("Invalid sec
");
}
$str .= "'$1',";
# There are no image, meta, file name, or data unit for this type
$str .= "'$Args::args{'host'}','','','','',";
unless ((exists $Args::args{'src'}) && ($Args::args{'src'} =~ /^(\w+)$/)) {
Print::print_err("Invalid src
");
}
$str .= "'$1','$Args::args{'note'}'\n";
# Write the string to the notes file
my $notes_file = investig_seq_notes_fname();
open NOTES, ">>$notes_file" or die "Can't open log: $notes_file";
print NOTES $str;
close(NOTES);
# Send a message to the user
print "Event Added to Sequencer file:
\n"
. "$::d2m[$Args::args{'mon'}] $Args::args{'day'}, $Args::args{'year'} "
. "$Args::args{'hour'}:$Args::args{'min'}:$Args::args{'sec'}
\n"
. "$Args::args{'note'}
\n"
. "
"
. "\n";
Print::print_html_footer();
return 0;
}
# View the sequencer file
sub read_seq {
Print::print_html_header("Event Sequencer");
print "
Date & Time | \n" . "Source | \n" . "Event & Note |
---|---|---|
\n" . "$::d2m[$mon[$i]] $day[$i], $year[$i]" . " $hour[$i]:$min[$i]:$sec[$i] | " . "\n"; # If there is as name, then we will show it # @@@ Why does an error message come up from here: # Use of uninitialized value in string ne at if ($fname[$i] ne "") { if ( (exists $vol[$i]) && (defined $vol[$i]) && ($vol[$i] ne "") && (exists $Caseman::vol2mnt{$vol[$i]}) && (exists $meta[$i])) { # extract the prepended mnt value my $mnt = $Caseman::vol2mnt{$vol[$i]}; my $fname = ""; $fname = $1 if ($fname[$i] =~ /^$mnt\/?(.*)$/); # Check if it is a directory if ($type[$i] eq 'dir') { print "\n" . "$fname[$i]\n"; } else { print "\n" . "$fname[$i]\n"; } } else { print "$fname[$i]\n"; } } # Display the meta value if there was no name elsif (($vol[$i] ne "") && (defined $meta[$i]) && ($meta[$i] ne "")) { my $ftype = $Caseman::vol2ftype{$vol[$i]}; # Include a link if we can if (exists $Caseman::vol2mnt{$vol[$i]}) { print "\n" . "$Fs::meta_str{$ftype}: $meta[$i]\n"; } else { print "$Fs::meta_str{$ftype}: $meta[$i]\n"; } } # Otherwise, just give the source type else { print "$type[$i]\n"; } print " | \n"; # Print the actual note $note[$i] = " " if ($note[$i] eq ""); print "$note[$i] |
\n"
. ""
. "![]() | \n"
. ""
. "![]() |