1package Print; 2 3# 4# Utilities to print information 5# 6# Brian Carrier [carrier@sleuthkit.org] 7# Copyright (c) 2001-2005 by Brian Carrier. All rights reserved 8# 9# This file is part of the Autopsy Forensic Browser (Autopsy) 10# 11# Autopsy is free software; you can redistribute it and/or modify 12# it under the terms of the GNU General Public License as published by 13# the Free Software Foundation; either version 2 of the License, or 14# (at your option) any later version. 15# 16# Autopsy is distributed in the hope that it will be useful, 17# but WITHOUT ANY WARRANTY; without even the implied warranty of 18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19# GNU General Public License for more details. 20# 21# You should have received a copy of the GNU General Public License 22# along with Autopsy; if not, write to the Free Software 23# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24# 25# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 26# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 27# MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. 28# IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 29# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30# (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR 31# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 32# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 33# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 34# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 36# Escape HTML entities 37# Converts \n to <br>\n 38sub html_encode { 39 my $text = shift; 40 $text =~ s/&/&/gs; 41 $text =~ s/</</gs; 42 $text =~ s/>/>/gs; 43 $text =~ s/\"/"/gs; 44 $text =~ s/\n/<br>\n/gs; 45 46 # @@@ LEADING SPACES and TABS 47 # while ($text =~ s/^( )*\t/"$1 "/eig) {} 48 # while ($text =~ s/^( )* /"$1 "/eig) {} 49 return $text; 50} 51 52# remove control chars from printout 53# this does not escape HTML entities, so you can pass this HTML code 54sub print_output { 55 my $out = shift; 56 print "$out"; 57 58 while (my $out = shift) { 59 foreach $_ (split(//, $out)) { 60 if ( ($_ eq "\n") 61 || ($_ eq "\r") 62 || ($_ eq "\f") 63 || ($_ eq "\t")) 64 { 65 print "$_"; 66 } 67 elsif ((ord($_) < 0x20) && (ord($_) >= 0x00)) { 68 print "^" . ord($_); 69 } 70 else { 71 print "$_"; 72 } 73 } 74 } 75} 76 77# Added to provide output in hexdump format 78# function gets called on a per-icat basis, 79# The offset value is the byte offset that this data 80# starts at, since the File.pm code calls it in 1024 81# byte chunks) 82sub print_hexdump { 83 my $out = shift; # data to output 84 my $offset = shift; # starting byte offset in file 85 my $buf = ""; 86 87 foreach $i (split(//, $out)) { 88 my $idx = $offset % 16; 89 90 if ($idx == 0) { 91 printf("%08X: ", $offset); 92 } 93 94 printf("%02X", ord($i)); 95 if (($idx % 2) == 1) { 96 printf(" "); 97 } 98 99 $buf[$idx] = $i; 100 101 if ($idx == 15) { 102 print " "; 103 for (my $j = 0; $j < 16; $j++) { 104 if ($buf[$j] =~ m/[ -~]/) { 105 print $buf[$j]; 106 } 107 else { 108 print "."; 109 } 110 $buf[$j] = 0; 111 } 112 print "\n"; 113 } 114 $offset++; 115 } 116 117 # print out last line if < 16 bytes long 118 my $l = $offset % 16; 119 120 if ($l) { 121 my $t = (16 - $l) * 2 + (16 - $l) / 2; 122 for (my $j = 0; $j < $t; $j++) { 123 print " "; 124 } 125 print " "; 126 for (my $j = 0; $j < $l; $j++) { 127 if ($buf[$j] =~ m/[ -~]/) { 128 print $buf[$j]; 129 } 130 else { 131 print "."; 132 } 133 } 134 print "\n"; 135 } 136} 137 138############################################ 139# 140# HTTP/HTML Headers and Footers 141 142# The page that makes the frameset does not have a body statement 143# This routine is used to make the minimum required header statements 144sub print_html_header_frameset { 145 my $text = shift; 146 print "Content-Type: text/html; charset=utf-8$::HTTP_NL$::HTTP_NL"; 147 148 my $time = localtime(); 149 150 print <<EOF; 151<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 152<html> 153<!-- Autopsy ver. $::VER Forensic Browser --> 154<!-- Page created at: $time --> 155<head> 156 <title>$text</title> 157 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 158 <link rel="stylesheet" href="global.css"> 159</head> 160 161EOF 162} 163 164sub print_html_footer_frameset { 165 print "\n</html>\n" . "$::HTTP_NL$::HTTP_NL"; 166} 167 168# Create the header information with the body tag 169sub print_html_header { 170 print_html_header_frameset(shift); 171 print "<body bgcolor=\"$::BACK_COLOR\">\n\n"; 172 print "<link rel=\"SHORTCUT ICON\" href=\"pict/favicon.ico\">\n"; 173} 174 175sub print_html_footer { 176 print "\n</body>\n</html>\n" . "$::HTTP_NL$::HTTP_NL"; 177} 178 179# Print the header with the margins set to 0 so that the tab buttons 180# are flush with the edges of the frame 181sub print_html_header_tabs { 182 print_html_header_frameset(shift); 183 print "<body marginheight=0 marginwidth=0 topmargin=0 " 184 . "leftmargin=0 rightmargin=0 botmargin=0 bgcolor=\"$::BACK_COLOR\">\n\n"; 185 print "<link rel=\"SHORTCUT ICON\" href=\"pict/favicon.ico\">\n"; 186 $is_body = 1; 187} 188 189sub print_html_footer_tabs { 190 print "\n</body>\n</html>\n" . "$::HTTP_NL$::HTTP_NL"; 191} 192 193# Header for front page to warn about java script 194sub print_html_header_javascript { 195 my $text = shift; 196 print "Content-Type: text/html; charset=utf-8$::HTTP_NL$::HTTP_NL"; 197 198 my $time = localtime(); 199 200 # The write line has to stay on one line 201 print <<EOF; 202<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 203<html> 204<!-- Autopsy ver. $::VER Forensic Browser --> 205<!-- Page created at: $time --> 206<head> 207 <title>$text</title> 208 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 209 <link rel="stylesheet" href="global.css"> 210 <script language=\"JavaScript\"> 211 <!-- hide script from old browsers 212 document.write(\'<center><font color=\"red\"><p>WARNING: Your browser currently has Java Script enabled.</font><p>You do not need Java Script to use Autopsy and it is recommended that it be turned off for security reasons.<hr></center>\'); 213 //--> 214 </script> 215</head> 216 217<body bgcolor=\"$::BACK_COLOR\"> 218<link rel=\"SHORTCUT ICON\" href=\"pict/favicon.ico\"> 219 220EOF 221} 222 223sub print_html_footer_javascript { 224 print "\n</body>\n</html>\n" . "$::HTTP_NL$::HTTP_NL"; 225} 226 227# For raw text outputs (Pass the name of a file if it is being saved) 228sub print_text_header { 229 print "Content-Type: text/plain; charset=utf-8$::HTTP_NL"; 230 if (scalar @_ > 0) { 231 my $fname = shift(); 232 print "Content-Disposition: inline; " . "filename=$fname;$::HTTP_NL"; 233 } 234 print "$::HTTP_NL"; 235} 236 237sub print_text_footer { 238 print "$::HTTP_NL$::HTTP_NL"; 239} 240 241# For forced save outputs 242sub print_oct_header { 243 print "Content-Type: application/octet-stream$::HTTP_NL"; 244 if (scalar @_ > 0) { 245 my $fname = shift(); 246 print "Content-Disposition: inline; " . "filename=$fname;$::HTTP_NL"; 247 } 248 print "$::HTTP_NL"; 249} 250 251sub print_oct_footer { 252} 253 254# Error message that is used when an HTTP/HTML header is needed 255# This escapes the characters that chould be HTML entities. 256# it will also replace \n with <br> and other things that html_encode() 257# can do. Do not send arbitrary HTML to this function. 258sub print_check_err { 259 print_html_header(""); 260 print html_encode(shift()) . "<br>\n"; 261 print_html_footer(); 262 sleep(1); 263 exit 1; 264} 265 266# Error message when header already exists 267# This escapes the characters that chould be HTML entities. 268# it will also replace \n with <br> and other things that html_encode() 269# can do. Do not send arbitrary HTML to this function. 270sub print_err { 271 print html_encode(shift()) . "<br>\n"; 272 sleep(1); 273 print_html_footer(); 274 exit 1; 275} 276 277################################################################## 278# 279# Logging 280# 281# 282 283sub investig_log_fname { 284 return "" unless (defined $::host_dir && $::host_dir ne ""); 285 return "" unless (exists $Args::args{'inv'} && $Args::args{'inv'} ne ""); 286 287 return "$::host_dir" . "$::LOGDIR/$Args::args{'inv'}.log"; 288} 289 290sub investig_exec_log_fname { 291 return "" unless (defined $::host_dir && $::host_dir ne ""); 292 return "" unless (exists $Args::args{'inv'} && $Args::args{'inv'} ne ""); 293 294 return "$::host_dir" . "$::LOGDIR/$Args::args{'inv'}.exec.log"; 295} 296 297sub host_log_fname { 298 return "" unless (defined $::host_dir && $::host_dir ne ""); 299 300 return "$::host_dir" . "$::LOGDIR/host.log"; 301} 302 303sub case_log_fname { 304 return "" unless (defined $::case_dir && $::case_dir ne ""); 305 306 return "$::case_dir" . "case.log"; 307} 308 309# Log data to the investigators specific log file 310sub log_host_inv { 311 return unless ($::USE_LOG == 1); 312 313 my $str = shift; 314 chomp $str; 315 316 my $date = localtime; 317 my $fname = investig_log_fname(); 318 return if ($fname eq ""); 319 320 open HOSTLOG, ">>$fname" or die "Can't open log: $fname"; 321 print HOSTLOG "$date: $str\n"; 322 close(HOSTLOG); 323 324 return; 325} 326 327sub log_host_inv_exec { 328 return unless ($::USE_LOG == 1); 329 my $str = shift; 330 chomp $str; 331 332 my $date = localtime; 333 my $fname = investig_exec_log_fname(); 334 return if ($fname eq ""); 335 336 open HOSTLOG, ">>$fname" or die "Can't open log: $fname"; 337 print HOSTLOG "$date: $str\n"; 338 close(HOSTLOG); 339 340 return; 341} 342 343# log data to the general log file for the host 344sub log_host_info { 345 return unless ($::USE_LOG == 1); 346 347 my $str = shift; 348 chomp $str; 349 350 my $date = localtime; 351 my $fname = host_log_fname(); 352 return if ($fname eq ""); 353 354 open HOSTLOG, ">>$fname" or die "Can't open log: $fname"; 355 print HOSTLOG "$date: $str\n"; 356 close(HOSTLOG); 357 358 return; 359} 360 361sub log_case_info { 362 return unless ($::USE_LOG == 1); 363 my $str = shift; 364 chomp $str; 365 my $date = localtime; 366 my $fname = case_log_fname(); 367 return if ($fname eq ""); 368 369 open CASELOG, ">>$fname" or die "Can't open log: $fname"; 370 print CASELOG "$date: $str\n"; 371 close(CASELOG); 372 373 return; 374} 375 376sub log_session_info { 377 return unless ($::USE_LOG == 1); 378 my $str = shift; 379 chomp $str; 380 my $date = localtime; 381 382 my $lname = "autopsy.log"; 383 open AUTLOG, ">>$::LOCKDIR/$lname" or die "Can't open log: $lname"; 384 print AUTLOG "$date: $str\n"; 385 close(AUTLOG); 386 387 return; 388} 389 3901; 391