[Forensics-changes] [SCM] debian-forensics/tableau-parm branch, debian, updated. debian/0.1.0-5-7-g9276593
Christophe Monniez
christophe.monniez at fccu.be
Sun Nov 1 22:49:56 UTC 2009
The following commit has been merged in the debian branch:
commit 2485a2dded08ef7603191d6af3166b34854ce77e
Author: Christophe Monniez <christophe.monniez at fccu.be>
Date: Sun Nov 1 23:10:22 2009 +0100
Merging upstream version 0.2.0.
diff --git a/INSTALL b/INSTALL
index 9883f98..7f8b1d3 100644
--- a/INSTALL
+++ b/INSTALL
@@ -7,8 +7,10 @@ Prerequisites
This package doesn't require much for installation. Just what typically
comes with any free operating system. Be sure you have:
- - Linux (currently not ported to other UN*X systems)
- - /usr/include/scsi/sg.h (on Debian, comes with libc6-dev package)
+ - sg3_utils header files and libraries
+ See: http://sg.danny.cz/sg/sg3_utils.html
+ - Linux or FreeBSD
+ Other platforms supported by sg3_utils may work, but haven't been tested
- Make
- GCC
@@ -21,6 +23,52 @@ make
make install
+Linux Notes
+-----------
+
+First ensure sg3_utils is installed.
+
+Under Debian, 'apt-get install sg3_utils' should be sufficient.
+In general, you should see the following files available on your
+system if you have the prerequisites installed correctly:
+ /usr/lib/libsgutils.so
+ /usr/include/scsi/sg_lib.h
+ /usr/include/scsi/sg_pt.h
+
+Tableau devices have only been tested over Firewire and USB. You
+should be able to run tableau-parm directly on disk devices, such as
+/dev/sda.
+
+
+FreeBSD Notes
+-------------
+
+First make sure your kernel supports the new SCSI generic (sg)
+interface for SCSI devices. During testing (which has only occurred
+on FreeBSD 7.2-RELEASE), it was necessary to add the following lines
+to the GENERIC kernel configuration:
+ device atapicam
+ device sg
+
+Once you recompile and reboot, you should see two new devices named
+'/dev/sg?' for each SCSI-like disk device on your system. For
+instance, on my test system, my main system disk had /dev/sg0 and
+/dev/sga associated with it. Adding a USB drive created /dev/da0 and
+associated /dev/sg1 and /dev/sg0. I don't yet know of a way to check
+to find out what base device an sg? device is associated with. In any
+case, using tableau-parm on sgN devices (where N is an integer) and
+directly on the base block device (such as /dev/da0) worked fine during
+preliminary testing.
+
+Once you have generic SCSI support, be sure sg3_utils is installed.
+There's a port under /usr/ports/sysutils/sg3_utils for the package.
+To ensure it is installed correctly, just check to make sure the
+following files exist:
+ /usr/local/lib/libsgutils.so
+ /usr/local/include/scsi/sg_lib.h
+ /usr/local/include/scsi/sg_pt.h
+
+
Advanced Installation
---------------------
To install in a custom directory, simply change one or more of the
diff --git a/Makefile b/Makefile
index d8ba518..b07abcd 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
# Makefile for tableau-parm
#
-# $Id: Makefile 27 2007-07-20 11:57:34Z tim $
+# $Id: Makefile 28 2009-09-29 01:25:39Z tim $
# Installation prefixes. Change to install elsewhere.
@@ -23,14 +23,15 @@ build/bin:
mkdir -p build/bin
build/bin/tableau-parm: build/bin src/tableau-parm.c Makefile
- $(CC) $(OPTS) -o $@ src/tableau-parm.c
+ $(CC) $(OPTS) -o $@ -I/usr/local/include -L/usr/local/lib -lsgutils src/tableau-parm.c
build/doc/man/man1/tableau-parm.1.gz: doc/man/man1/tableau-parm.1.gz
mkdir -p build/doc/man/man1
cp doc/man/man1/tableau-parm.1.gz $@
install: all
- install -D build/bin/tableau-parm $(BIN_PREFIX)/tableau-parm
+ mkdir -p $(BIN_PREFIX)
+ install build/bin/tableau-parm $(BIN_PREFIX)/tableau-parm
mkdir -p $(DOC_PREFIX)
cp -r build/doc/man $(DOC_PREFIX)
ln -sf $(DOC_PREFIX)/man/man1/* $(MAN_PREFIX)/man1
diff --git a/doc/Makefile b/doc/Makefile
index bd2ec71..aa80a60 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -1,7 +1,7 @@
-# $Id: Makefile 20 2007-07-19 13:57:44Z tim $
+# $Id: Makefile 30 2009-09-29 18:52:10Z tim $
#XXX: Used during release only
release:
- docbook2x-man --to-stdout tableau-parm.1.docbook > man/man1/tableau-parm.1
+ docbook2x-man --to-stdout tableau-parm.1.docbook | sed 's/.SH DESCRIPTION/\n.SH DESCRIPTION/' > man/man1/tableau-parm.1
cd man/man1 && gzip -9 -f tableau-parm.1
diff --git a/doc/man/man1/tableau-parm.1.gz b/doc/man/man1/tableau-parm.1.gz
index 9143ec3..0bcdf50 100644
Binary files a/doc/man/man1/tableau-parm.1.gz and b/doc/man/man1/tableau-parm.1.gz differ
diff --git a/doc/tableau-parm.1.docbook b/doc/tableau-parm.1.docbook
index 18e0ec2..21b26a2 100644
--- a/doc/tableau-parm.1.docbook
+++ b/doc/tableau-parm.1.docbook
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<refentry id='tableau-parm.1'>
- <!-- $Id: tableau-parm.1.docbook 21 2007-07-19 14:08:25Z tim $ -->
+ <!-- $Id: tableau-parm.1.docbook 30 2009-09-29 18:52:10Z tim $ -->
<refmeta>
<refentrytitle>tableau-parm</refentrytitle>
<manvolnum>1</manvolnum>
@@ -124,10 +124,10 @@
<refsect1 id='credits'>
<title>CREDITS</title>
<para>
- Copyright (C) 2007 Timothy D. Morgan
+ Copyright (C) 2007,2009 Timothy D. Morgan
</para>
<para>
- Copyright (C) 1999,2001 D. Gilbert
+ Copyright (C) 1999,2001,2006,2007 D. Gilbert
</para>
<para>
<command>tableau-parm</command> was written by Timothy D. Morgan using
diff --git a/src/tableau-parm.c b/src/tableau-parm.c
index 6bd47a2..cbc5b77 100644
--- a/src/tableau-parm.c
+++ b/src/tableau-parm.c
@@ -7,8 +7,8 @@
* provided by Tableau, LLC. (http://www.tableau.com/) Tableau does not
* endorse or warrant this software in any way.
*
- * Copyright (C) 2007 Timothy D. Morgan
- * Copyright (C) 1999,2001 D. Gilbert
+ * Copyright (C) 2007,2009 Timothy D. Morgan
+ * Copyright (C) 1999,2001,2006,2007 D. Gilbert
*
* 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
@@ -23,7 +23,7 @@
* version 3, along with this program. If not, see:
* http://www.gnu.org/licenses/.
*
- * $Id: tableau-parm.c 22 2007-07-19 20:17:03Z tim $
+ * $Id: tableau-parm.c 29 2009-09-29 04:47:16Z tim $
*/
#include <stdio.h>
@@ -34,8 +34,9 @@
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
-#include <scsi/sg.h>
+#include <scsi/sg_lib.h>
+#include <scsi/sg_pt.h>
#define TABLEAU_SCSI_CMD 0xEC
#define TABLEAU_HEADER_LEN 120
@@ -44,18 +45,18 @@
#define SENSE_LEN 64
#define RECV_LEN 255
-
+#define CMD_TIMEOUT_SECS 20
void usage()
{
fprintf(stderr, "Usage: tableau-parm [-r] <DEVICE>\n");
- fprintf(stderr, "Version: 0.1.0\n\n");
+ fprintf(stderr, "Version: 0.2.0\n\n");
fprintf(stderr, "\tDEVICE\t\tA SCSI block device, such as /dev/sd?\n\n");
fprintf(stderr, "\t-r\t\tRemoves DCO (and possibly HPA) from the device.\n");
fprintf(stderr, "\t\t\tTHIS WILL MODIFY THE STATE OF THE DEVICE!!\n");
fprintf(stderr, "\n");
- fprintf(stderr, "Copyright (C) 2007 Timothy D. Morgan\n");
- fprintf(stderr, "Copyright (C) 1999,2001 D. Gilbert\n\n");
+ fprintf(stderr, "Copyright (C) 2007,2009 Timothy D. Morgan\n");
+ fprintf(stderr, "Copyright (C) 1999,2001,2006,2007 D. Gilbert\n\n");
fprintf(stderr, "This program comes with ABSOLUTELY NO WARRANTY.\n");
fprintf(stderr, "This is free software, and you are welcome to redistribute it\n");
fprintf(stderr, "under the conditions of the GNU Public License, version 3.\n");
@@ -72,8 +73,8 @@ void bailOut(int code, char* message)
/* Returns a newly malloc()ed string which contains original buffer,
* except for non-printable or special characters are quoted in hex
- * with the syntax '\xQQ' where QQ is the hex ascii value of the quoted
- * character. A null terminator is added, since only ascii, not binary,
+ * with the syntax '%QQ' where QQ is the hex value of the quoted
+ * character. A NUL terminator is added, since only ascii, not binary,
* is returned.
*/
static char* quote_buffer(const unsigned char* str,
@@ -100,12 +101,12 @@ static char* quote_buffer(const unsigned char* str,
* reallocs() and the amount of wasted memory.
*/
added_len = (len-i)*num_written/(i+1);
- if((buf_len+added_len) > (len*4+1))
- buf_len = len*4+1;
+ if((buf_len+added_len) > (len*3+1))
+ buf_len = len*3+1;
else
{
- if (added_len < 5)
- buf_len += 5;
+ if (added_len < 4)
+ buf_len += 4;
else
buf_len += added_len;
}
@@ -119,10 +120,11 @@ static char* quote_buffer(const unsigned char* str,
ret_val = tmp_buf;
}
- if(str[i] < 32 || str[i] > 126 || strchr(special, str[i]) != NULL)
+ if(str[i] < 32 || str[i] > 126 || str[i] == '%'
+ || strchr(special, str[i]) != NULL)
{
num_written += snprintf(ret_val + num_written, buf_len - num_written,
- "\\x%.2X", str[i]);
+ "%%%.2X", str[i]);
}
else
ret_val[num_written++] = str[i];
@@ -133,14 +135,20 @@ static char* quote_buffer(const unsigned char* str,
}
-/* Trims spaces off of string fields and quotes any non-printables. */
+/* Trims spaces off of beginning and end of string fields and
+ * quotes any non-printables.
+ */
char* convertStringField(const unsigned char* f, unsigned short flen)
{
int i;
for(i=flen-1; (i >= 0) && (f[i] == ' '); i--)
continue;
- return quote_buffer(f, i+1, "");
+ flen = i+1;
+ for(; (flen > 0) && (f[0] == ' '); flen--,f++)
+ continue;
+
+ return quote_buffer(f, flen, "");
}
@@ -162,7 +170,6 @@ const unsigned char* printQueryResponse(const unsigned char* recv_b)
bool declare_write_blocked;
bool declare_write_errors;
- /*char* bridge_serial;*/
char* bridge_vendor;
char* bridge_model;
char* firmware_date;
@@ -322,7 +329,7 @@ const unsigned char* printQueryResponse(const unsigned char* recv_b)
ret_val = recv_b+(next_page_off+28);
if(hpa_disable_err_code != 0)
- fprintf(stderr, "WARNING: HPA section could not be automatically, "
+ fprintf(stderr, "WARN: HPA section could not be automatically, "
"temporarily disabled! Error code: %d\n",hpa_disable_err_code);
break;
@@ -339,64 +346,103 @@ const unsigned char* printQueryResponse(const unsigned char* recv_b)
}
-int sendCommand(int dev_fd,
+int sendCommand(int sg_fd,
unsigned char* cmd_block, unsigned int cmd_block_len,
unsigned char* recv_b, unsigned int recv_len,
- unsigned char* sense_b, unsigned int sense_len)
+ unsigned char* sense_b, unsigned int sense_len,
+ bool verbose)
{
- struct sg_io_hdr io_hdr;
- unsigned int i;
+ int res, resid, cat, slen;
+ char err_b[512];
+ struct sg_pt_base* ptvp;
+
+ /* one object per command */
+ ptvp = construct_scsi_pt_obj();
+ if (NULL == ptvp)
+ {
+ fprintf(stderr, "ERROR: construct_scsi_pt_obj failed. "
+ "Memory allocation failure likely.\n");
+ return -1;
+ }
+
+ set_scsi_pt_cdb(ptvp, cmd_block, cmd_block_len);
+ set_scsi_pt_sense(ptvp, sense_b, sense_len);
+ set_scsi_pt_data_in(ptvp, recv_b, recv_len);
+ res = do_scsi_pt(ptvp, sg_fd, CMD_TIMEOUT_SECS, 0);
+ if (res < 0)
+ {
+ fprintf(stderr, "ERROR: do_scsi_pt returned: %s\n", strerror(-res));
+ goto error;
+ }
+
+ if (SCSI_PT_DO_BAD_PARAMS == res)
+ {
+ fprintf(stderr, "ERROR: do_scsi_pt returned SCSI_PT_DO_BAD_PARAMS.\n");
+ goto error;
+ }
- memset(recv_b, 0, recv_len);
- memset(sense_b, 0, sense_len);
- memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
- io_hdr.interface_id = 'S';
- io_hdr.cmdp = cmd_block;
- io_hdr.cmd_len = cmd_block_len;
- io_hdr.sbp = sense_b;
- io_hdr.mx_sb_len = sense_len;
- io_hdr.dxferp = recv_b;
- io_hdr.dxfer_len = recv_len;
- /*io_hdr.dxfer_direction = (cmd_block_len == 6) ? SG_DXFER_FROM_DEV : SG_DXFER_TO_FROM_DEV;*/
- io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
- io_hdr.timeout = 30000; /* 30 sec */
-
- if (ioctl(dev_fd, SG_IO, &io_hdr) < 0)
+ if (SCSI_PT_DO_TIMEOUT == res)
{
- perror("ERROR: ioctl failed");
- fprintf(stderr, "ERROR: Could not query device.\n");
- return 3;
+ fprintf(stderr, "ERROR: do_scsi_pt returned SCSI_PT_DO_TIMEOUT.\n");
+ goto error;
}
- /* Check for errors coming from the device */
- if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK)
+ resid = get_scsi_pt_resid(ptvp);
+ if (verbose && (resid > 0))
+ fprintf(stderr, "WARN: Requested %d bytes but got %d bytes)\n",
+ recv_len, recv_len - resid);
+
+ switch ((cat = get_scsi_pt_result_category(ptvp)))
{
- if (io_hdr.sb_len_wr > 0)
+ case SCSI_PT_RESULT_GOOD:
+ break;
+
+ /* other than GOOD and CHECK CONDITION */
+ case SCSI_PT_RESULT_STATUS:
+ if (verbose)
{
- fprintf(stderr, "ERROR: INQUIRY sense data:");
- for (i = 0; i < io_hdr.sb_len_wr; i++)
- {
- if((i % 16) == 0)
- fprintf(stderr, "\n");
- fprintf(stderr, " %.2X", sense_b[i]);
- }
- fprintf(stderr, "\n");
+ sg_get_scsi_status_str(get_scsi_pt_status_response(ptvp), sizeof(err_b), err_b);
+ fprintf(stderr, "WARN: SCSI status: %s\n", err_b);
}
- if (io_hdr.masked_status)
- fprintf(stderr, "ERROR: INQUIRY SCSI status=%X\n", io_hdr.status);
- if (io_hdr.host_status)
- fprintf(stderr, "ERROR: INQUIRY host_status=%X\n", io_hdr.host_status);
- if (io_hdr.driver_status)
- fprintf(stderr, "ERROR: INQUIRY driver_status=%X\n", io_hdr.driver_status);
-
- fprintf(stderr, "ERROR: SCSI response not OK. Cannot continue.\n");
- return 5;
- }
+ break;
+
+ case SCSI_PT_RESULT_SENSE:
+ if (verbose)
+ {
+ slen = get_scsi_pt_sense_len(ptvp);
+ sg_get_sense_str("", sense_b, slen, 1, sizeof(err_b), err_b);
+ fprintf(stderr, "WARN: Sense string: %s\n", err_b);
+ }
+ break;
+
+ case SCSI_PT_RESULT_TRANSPORT_ERR:
+ if (verbose)
+ {
+ get_scsi_pt_transport_err_str(ptvp, sizeof(err_b), err_b);
+ fprintf(stderr, "WARN: Transport error: %s\n", err_b);
+ }
+ break;
+
+ case SCSI_PT_RESULT_OS_ERR:
+ if (verbose)
+ {
+ get_scsi_pt_os_err_str(ptvp, sizeof(err_b), err_b);
+ fprintf(stderr, "WARN: OS Error: %s\n", err_b);
+ }
+ break;
+
+ default:
+ fprintf(stderr, "ERROR: Unknown pass through result category (%d)\n", cat);
+ break;
+ }
+ destruct_scsi_pt_obj(ptvp);
return 0;
-}
-
+ error:
+ destruct_scsi_pt_obj(ptvp);
+ return 1;
+}
int main(int argc, char** argv)
@@ -429,15 +475,16 @@ int main(int argc, char** argv)
/* XXX: What if this isn't a tableau device?
* Can we detect this before we query?
*/
- sg_fd = open(dev_file, O_RDONLY);
- if(sg_fd == -1)
- {
- perror("ERROR: open failed");
- bailOut(3, "ERROR: Could not open device.\n");
+ sg_fd = scsi_pt_open_device(dev_file, 0 /* rw */, 0);
+ if (sg_fd < 0) {
+ fprintf(stderr, "ERROR: scsi_pt_open_device failed on '%s' with: %s\n",
+ dev_file, strerror(-sg_fd));
+ return 1;
}
cmd_ret = sendCommand(sg_fd, tableau_query_cmd, 6,
- recv_b, RECV_LEN, sense_b, SENSE_LEN);
+ recv_b, RECV_LEN, sense_b, SENSE_LEN,
+ true);
if(cmd_ret != 0)
bailOut(cmd_ret, "ERROR: Query command failed.\n");
@@ -460,7 +507,8 @@ int main(int argc, char** argv)
tableau_dco_restore_cmd[8] = dco_challenge_key[3];
cmd_ret = sendCommand(sg_fd, tableau_dco_restore_cmd, 12,
- recv_b, RECV_LEN, sense_b, SENSE_LEN);
+ recv_b, RECV_LEN, sense_b, SENSE_LEN,
+ true);
if(cmd_ret != 0)
bailOut(cmd_ret, "ERROR: DCO restore command failed.\n");
@@ -471,8 +519,8 @@ int main(int argc, char** argv)
}
else
printf("\n## DCO removal requested, but DCO no found! Quitting. ##\n");
- }
- close(sg_fd);
+ }
+ scsi_pt_close_device(sg_fd);
return 0;
}
--
debian-forensics/tableau-parm
More information about the forensics-changes
mailing list