Files
chipsec-chipsec/source/tool/chipsec/logger.py
T
CHIPSEC ac2ca7264f 1. We have support for uefi variables on Windows and Linux but not
UEFI shell.
2.       Decompression of images in SPI flash parsing is only supported in
Windows.
3.	UEFI - Support for IA32 and i586 (Quark)
4.	Added capability to use modules from an arbitrary path with the -I
/ --import command line option
5.	Module functionality encapsulated in class inheriting BaseModule
6.	Fixed  loading platform specific configuration
7.	Fixed issue with modules which run on multiple logical CPUs
hanging on Bay Trail (Windows/Linux). The issue still exist when running
from UEFI shell
8.	Added template for a module - module_template.py
9.	Added options to flush log files
10.	Added ability to define custom platforms
Driver changes:
1.	Windows - Added IOCTL_ALLOC_PHYSMEM to allocate physical memory
buffer
2.	Linux - Fix wrpci defect
2014-05-29 21:57:40 +01:00

443 lines
14 KiB
Python

#!/usr/local/bin/python
#CHIPSEC: Platform Security Assessment Framework
#Copyright (c) 2010-2014, Intel Corporation
#
#This program 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; Version 2.
#
#This program 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 this program; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#Contact information:
#chipsec@intel.com
#
# -------------------------------------------------------------------------------
#
# CHIPSEC: Platform Hardware Security Assessment Framework
# (c) 2010-2012 Intel Corporation
#
# -------------------------------------------------------------------------------
## \addtogroup core
# __chipsec/logger.py__ - logging functions
#
#
import platform
import string
import sys
import os
from time import localtime, strftime
from chipsec.xmlout import xmlAux
import traceback
RESET =0
BRIGHT =1
DIM =2
UNDERLINE =3
BLINK =4
REVERSE =7
HIDDEN =8
BLACK =0
RED =1
GREEN =2
YELLOW =3
BLUE =4
MAGENTA =5
CYAN =6
WHITE =7
LOG_PATH = os.path.join( os.getcwd(), "logs" )
#LOG_STATUS_FILE_NAME = ""
#LOG_COMPLETED_FILE_NAME = ""
#
# Colored output
#
if "windows" == platform.system().lower():
try:
import WConio
COLOR_ID = {
BLACK : WConio.BLACK,
RED : WConio.LIGHTRED,
GREEN : WConio.LIGHTGREEN,
YELLOW : WConio.YELLOW,
BLUE : WConio.LIGHTBLUE,
MAGENTA: WConio.MAGENTA,
CYAN : WConio.CYAN,
WHITE : WConio.WHITE
}
def log_color( fg_color, text ):
# Store current attribute settings
old_setting = WConio.gettextinfo()[4] & 0x00FF
WConio.textattr( COLOR_ID[ fg_color ] )
print text
WConio.textattr( old_setting )
except ImportError, e:
#print "WConio package is not installed. No colored output"
def log_color( fg_color, text ):
print text
elif "linux" == platform.system().lower():
def log_color( fg_color, text ):
#_text = "\033[%dm" + text + "\033[0m" % (fg_color + 30) #FIXME: _text = "\033[%dm" + text + "\033[0m" % (fg_color + 30) \n TypeError: not all arguments converted during string formatting
print text #_text
else:
def log_color( fg_color, text ):
print text
class LoggerError (RuntimeWarning):
pass
class Logger:
"""Class for logging to console, text file or XML."""
def __init__( self ):
"""The Constructor."""
pass
self.mytime = localtime()
self.logfile = None
self.ALWAYS_FLUSH = False
#Used for interaction with XML output classes.
self.xmlAux = xmlAux()
#self._set_log_files()
def set_xml_file(self, name=None):
self.xmlAux.set_xml_file(name)
def saveXML(self):
self.xmlAux.saveXML()
def set_log_file( self, name=None ):
"""Sets the log file for the output."""
# Close current log file if it's opened
self.disable()
self.LOG_FILE_NAME = name
# specifying name=None effectively disables logging to file
if self.LOG_FILE_NAME:
# Open new log file and keep it opened
try:
self.logfile = open( self.LOG_FILE_NAME, 'a+' )
self.LOG_TO_FILE = True
except None:
print ("WARNING: Could not open log file '%s'" % name)
def set_default_log_file( self ):
"""Sets the default log file for the output."""
# Close current log file if it's opened
self.disable()
if not os.path.exists( LOG_PATH ): os.makedirs( LOG_PATH )
self.LOG_FILE_NAME = os.path.join( LOG_PATH, strftime( '%Y_%m_%d__%H%M%S', self.mytime ) + '.log')
# Open new log file and keep it opened
try:
self.logfile = open( self.LOG_FILE_NAME, 'a+' )
self.LOG_TO_FILE = True
except None:
print ("WARNING: Could not open log file '%s'" % self.LOG_FILE_NAME)
def set_status_log_file( self ):
"""Sets the status log file for the output."""
if not os.path.exists(LOG_PATH):
os.makedirs(LOG_PATH)
self.LOG_STATUS_FILE_NAME = os.path.join( LOG_PATH, strftime('%Y_%m_%d__%H%M%S', self.mytime ) + '_results.log')
self.LOG_TO_STATUS_FILE = True
def close( self ):
"""Closes the log file."""
if self.logfile:
try:
self.logfile.close()
except None:
print 'WARNING: Could not close log file'
finally:
self.logfile = None
def disable( self ):
"""Disables the logging to file and closes the file if any."""
self.LOG_TO_FILE = False
self.LOG_FILE_NAME = None
self.close()
#self.LOG_TO_STATUS_FILE = False
#self.LOG_STATUS_FILE_NAME = None
def __del__(self):
"""Disables the logger."""
self.disable()
######################################################################
# Logging functions
######################################################################
def flush(self):
sys.stdout.flush()
if self.LOG_TO_FILE and self.logfile is not None:
# not sure why flush doesn't work as excpected
# self.logfile.flush()
# close and re-open log file
try:
self.logfile.close()
self.logfile = open( self.LOG_FILE_NAME, 'a+' )
except None:
self.disable()
def set_always_flush( self, val ):
self.ALWAYS_FLUSH = val
def log( self, text):
"""Sends plain text to logging."""
self._log(text, None, None)
def _log(self, text, color, isStatus):
"""Internal method for logging"""
if self.LOG_TO_FILE: self._save_to_log_file( text )
else:
if color: log_color( color, text )
else:
print text
if self.ALWAYS_FLUSH: sys.stdout.flush()
if self.xmlAux.useXML: self.xmlAux.append_stdout(text)
if isStatus: self._save_to_status_log_file( text )
def error( self, text ):
"""Logs an Error message"""
text = "ERROR: " + text
self._log(text, RED, None)
def warn( self, text ):
"""Logs an Warning message"""
text = "WARNING: " + text
self._log(text, YELLOW, None)
def log_passed_check( self, text ):
"""Logs a Test as PASSED, this is used for XML output.
If XML file was not specified, then it will just print a PASSED test message.
"""
self.log_passed(text)
self.xmlAux.passed_check()
def log_failed_check( self, text ):
"""Logs a Test as FAILED, this is used for XML output.
If XML file was not specified, then it will just print a FAILED test message.
"""
self.log_failed(text)
self.xmlAux.failed_check( text )
def log_error_check( self, text ):
"""Logs a Test as ERROR, this is used for XML output.
If XML file was not specified, then it will just print a ERROR test message.
"""
self.error(text)
self.xmlAux.error_check( text )
def log_skipped_check( self, text ):
"""Logs a Test as SKIPPED, this is used for XML output.
If XML file was not specified, then it will just print a SKIPPED test message.
"""
self.log_skipped(text)
self.xmlAux.skipped_check( text )
def log_warn_check( self, text ):
"""Logs a Warning test, a warning test is considered equal to a PASSED test.
Logs a Test as PASSED, this is used for XML output."""
self.log_warning(text)
self.xmlAux.passed_check()
def log_passed( self, text ):
"""Logs a passed message."""
text = "[+] PASSED: " + text
self._log(text, GREEN, True)
def log_failed( self, text ):
"""Logs a failed message."""
text = "[-] FAILED: " + text
self._log(text, RED, True)
def log_warning( self, text ):
"""Logs a Warning message"""
text = "[!] WARNING: " + text
self._log(text, YELLOW, None)
#self.xmlAux.passed_check()
def log_skipped( self, text ):
"""Logs a skipped message."""
text = "[*] SKIPPED: " + text
self._log(text, YELLOW, True)
def log_heading( self, text ):
"""Logs a heading message."""
self._log(text, BLUE, None)
def log_important( self, text ):
"""Logs a important message."""
text = "[!] " + text
self._log(text, RED, None)
def log_result( self, text ):
"""Logs a result message."""
text = "[+] " + text
self._log(text, GREEN, None)
def log_bad( self, text ):
"""Logs a bad message, so it calls attention in the information displayed."""
text = "[-] " + text
self._log(text, RED, None)
def log_good( self, text ):
"""Logs a message, if colors available, displays in green."""
text = "[+] " + text
self._log(text, GREEN, None)
def log_unknown( self, text ):
"""Logs a message with a question mark."""
text = "[?] " + text
self._log(text, None, None)
def start_test( self, test_name ):
"""Logs the start point of a Test, this is used for XML output.
If XML file was not specified, it will just display a banner for the test name.
"""
text = "[x][ =======================================================================\n"
text = text + "[x][ Test: " + test_name + "\n"
text = text + "[x][ ======================================================================="
self._log(text, BLUE, True)
self.xmlAux.start_test( test_name )
def start_module( self, module_name ):
"""Displays a banner for the module name provided."""
text = "\n[+] imported %s" % module_name
self._log(text, WHITE, None)
self.xmlAux.start_module( module_name )
def end_module( self, module_name ):
#text = "\n[-] *** Done *** %s" % module_name
#self._log(text, None, None)
self.xmlAux.end_module( module_name )
def _write_log( self, text, filename ):
"""
#with open( filename, 'a+' ) as f:
# print >> f, text
f = open( filename, 'a+' )
try:
print >> f, text
finally:
f.close()
"""
print >> self.logfile, text
if self.ALWAYS_FLUSH:
# not sure why flush doesn't work as excpected
# self.logfile.flush()
# close and re-open log file
try:
self.logfile.close()
self.logfile = open( self.LOG_FILE_NAME, 'a+' )
except None:
self.disable()
def _save_to_status_log_file(self, text):
if(self.LOG_TO_STATUS_FILE):
self._write_log(text, self.LOG_STATUS_FILE_NAME)
def _save_to_log_file(self, text):
if(self.LOG_TO_FILE):
self._write_log(text, self.LOG_FILE_NAME)
VERBOSE = False
UTIL_TRACE = False
LOG_TO_STATUS_FILE = False
LOG_TO_FILE = False
LOG_STATUS_FILE_NAME = ""
LOG_FILE_NAME = ""
DEBUG = False
_logger = Logger()
def logger():
"""Returns a Logger instance."""
return _logger
##################################################################################
# Hex dump functions
##################################################################################
def dump_buffer( arr, length = 8 ):
"""Dumps the buffer."""
tmp=[]
tmp_str=[]
i=1
for c in arr:
tmp+=["%2.2x "%ord(c)]
#if 0xD == ord(c) or 0xA == ord(c):
if c in string.whitespace:
ch = " "
else:
ch = ord(c)
tmp_str+=["%c"%ch]
if i%length==0:
tmp+=["| "]
tmp+=tmp_str
tmp+=["\n"]
tmp_str=[]
#print tmp
#print "\n"
i+=1
if 0 != len(arr)%length:
tmp+=[ (length - len(arr)%length) * 3*" " ]
tmp+=["| "]
tmp+=tmp_str
tmp+=["\n"]
return "".join(tmp)
def print_buffer( arr, length = 16 ):
"""Prints the buffer."""
tmp=[]
tmp_str=[]
i=1
for c in arr:
tmp+=["%2.2x "%ord(c)]
if (not c in string.printable) or (c in string.whitespace):
ch = " "
else:
ch = ord(c)
tmp_str+=["%c"%ch]
if i%length==0:
tmp+=["| "]
tmp+=tmp_str
tmp_s = "".join(tmp)
logger().log( tmp_s )
tmp_str=[]
tmp=[]
i+=1
if 0 != len(arr)%length:
tmp+=[ (length - len(arr)%length) * 3*" " ]
tmp+=["| "]
tmp+=tmp_str
tmp_s = "".join(tmp)
logger().log( tmp_s )