[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