]> git.sur5r.net Git - bacula/bacula/commitdiff
SHA1 implementation
authorKern Sibbald <kern@sibbald.com>
Mon, 27 Jan 2003 12:02:40 +0000 (12:02 +0000)
committerKern Sibbald <kern@sibbald.com>
Mon, 27 Jan 2003 12:02:40 +0000 (12:02 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@325 91ce42f0-d328-0410-95d8-f526ca767f89

29 files changed:
bacula/kernstodo
bacula/src/baconfig.h
bacula/src/cats/bdb.c
bacula/src/cats/bdb_update.c
bacula/src/cats/cats.h
bacula/src/cats/protos.h
bacula/src/cats/sql_get.c
bacula/src/cats/sql_update.c
bacula/src/dird/catreq.c
bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/dird/fd_cmds.c
bacula/src/dird/verify.c
bacula/src/filed/backup.c
bacula/src/filed/restore.c
bacula/src/filed/verify.c
bacula/src/filed/verify_vol.c
bacula/src/findlib/find.h
bacula/src/findlib/match.c
bacula/src/lib/Makefile.in
bacula/src/lib/lib.h
bacula/src/lib/md5.c
bacula/src/lib/sha1.c
bacula/src/lib/sha1.h
bacula/src/stored/append.c
bacula/src/stored/bextract.c
bacula/src/stored/bscan.c
bacula/src/stored/mount.c
bacula/src/stored/record.c

index dca4df3e5e5d8909c0ed07fb3969f36196cf8bf7..3420d0843a178dccfd132dc7396f34e70a25b6eb 100644 (file)
@@ -15,6 +15,8 @@ Testing to do: (painful)
 - blocksize recognition code.
 
 For 1.30 release:
+- Add Signature type to File DB record.
+
 - CD into subdirectory when open()ing files for backup to
   speed up things.  Test with testfind().
 - Add prefixlinks to where or not where absolute links to FD.
index cc21842f8843a8bdb348d9330e4076fd44d299d8..a077b5b6bb869c6f535d2774354d337a03e26190 100644 (file)
 #define STREAM_SPARSE_GZIP_DATA  7
 #define STREAM_PROGRAM_NAMES     8    /* program names for program data */
 #define STREAM_PROGRAM_DATA      9    /* Data needing program */
+#define STREAM_SHA1_SIGNATURE   10    /* SHA1 signature for the file */
+
+/*
+ * Internal code for Signature types
+ */
+#define NO_SIG   0
+#define MD5_SIG  1
+#define SHA1_SIG 2
 
 /* Size of File Address stored in STREAM_SPARSE_DATA. Do NOT change! */
 #define SPARSE_FADDR_SIZE (sizeof(uint64_t))
index 7ed4282616ab7f8b0aeb2a818be570fc0a952ecd..d35bc53dac495c30992b49aa380480dc7aca6ccd 100644 (file)
@@ -128,6 +128,9 @@ db_init_database(void *jcr, char *db_name, char *db_user, char *db_password)
    Dmsg0(200, "Done db_open_database()\n");
    mdb->cfd = -1;
    V(mutex);
+   Jmsg(jcr, M_WARNING, 0, _("WARNING!!!! The Internal Database is for TESTING ONLY!\n"));
+   Jmsg(jcr, M_WARNING, 0, _("You should use either SQLite or MySQL\n"));
+
    return mdb;
 }
 
index 0a82099b49165af1909c7b3fe5e6087706c7d1e5..0b043af65e1bd83aa0a8b70b628f03e79ce46098 100755 (executable)
@@ -192,7 +192,7 @@ int db_update_pool_record(void *jcr, B_DB *mdb, POOL_DBR *pr)
    return stat;
 }
 
-int db_add_MD5_to_file_record(void *jcr, B_DB *mdb, FileId_t FileId, char *MD5)   
+int db_add_SIG_to_file_record(void *jcr, B_DB *mdb, FileId_t FileId, char *SIG, int type)
 {
    return 1;
 }
index c65ca3362f406816ec1105d8698a4071171db7b9..abd39a24040e6306c4764aeb65972d3465278aeb 100644 (file)
@@ -365,7 +365,8 @@ typedef struct {
    JobId_t  MarkId;
    char LStat[256];
 /*   int Status; */
-   char MD5[50];
+   char SIG[50];
+   int SigType;                       /* NO_SIG/MD5_SIG/SHA1_SIG */
 } FILE_DBR;
 
 /* Pool record -- same format as database */
index c1c4111dc87116641f566589e569d8840c0fca1a..a212423604307806b3b25ffd619cc73459365e4a 100644 (file)
@@ -94,7 +94,7 @@ int  db_update_job_start_record(void *jcr, B_DB *db, JOB_DBR *jr);
 int  db_update_job_end_record(void *jcr, B_DB *db, JOB_DBR *jr);
 int  db_update_pool_record(void *jcr, B_DB *db, POOL_DBR *pr);
 int  db_update_media_record(void *jcr, B_DB *db, MEDIA_DBR *mr);
-int  db_add_MD5_to_file_record(void *jcr, B_DB *mdb, FileId_t FileId, char *MD5);  
+int  db_add_SIG_to_file_record(void *jcr, B_DB *mdb, FileId_t FileId, char *SIG, int type);  
 int  db_mark_file_record(void *jcr, B_DB *mdb, FileId_t FileId, JobId_t JobId);
 
 #endif /* __SQL_PROTOS_H */
index 3568f1bf046d20a1d5b9f0e54adcc6939fbca973..bc6af6899d4af71d205ff5d5f37f9db3a1e526d3 100644 (file)
@@ -128,7 +128,7 @@ File.FilenameId=%u", fdbr->JobId, fdbr->PathId, fdbr->FilenameId);
         } else {
            fdbr->FileId = (FileId_t)str_to_int64(row[0]);
            bstrncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat));
-           bstrncpy(fdbr->MD5, row[2], sizeof(fdbr->MD5));
+           bstrncpy(fdbr->SIG, row[2], sizeof(fdbr->SIG));
            stat = 1;
         }
       } else {
index 0029261496dbbdcf77da47b11420f6ac948259f5..e127ae146741599fe628014af9291b04648a51fc 100644 (file)
@@ -55,12 +55,13 @@ extern int UpdateDB(char *file, int line, void *jcr, B_DB *db, char *update_cmd)
  */
 /* Update the attributes record by adding the MD5 signature */
 int
-db_add_MD5_to_file_record(void *jcr, B_DB *mdb, FileId_t FileId, char *MD5)
+db_add_SIG_to_file_record(void *jcr, B_DB *mdb, FileId_t FileId, char *SIG,
+                         int type)
 {
    int stat;
 
    db_lock(mdb);
-   Mmsg(&mdb->cmd, "UPDATE File SET MD5='%s' WHERE FileId=%u", MD5, FileId);
+   Mmsg(&mdb->cmd, "UPDATE File SET MD5='%s' WHERE FileId=%u", SIG, FileId);
    stat = UPDATE_DB(jcr, mdb, mdb->cmd);
    db_unlock(mdb);
    return stat;
index 0a74a5b79a4f0bb5130d215437261a63882f950d..f944bfaf330ad4f04bfb48c6bee6b45faef30e69 100644 (file)
@@ -382,20 +382,28 @@ void catalog_update(JCR *jcr, BSOCK *bs, char *msg)
       if (!db_create_file_attributes_record(jcr, jcr->db, &ar)) {
          Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db));
       }
-      /* Save values for MD5 update */
+      /* Save values for SIG update */
       jcr->FileId = ar.FileId;
       jcr->FileIndex = FileIndex;
-   } else if (Stream == STREAM_MD5_SIGNATURE) {
+   } else if (Stream == STREAM_MD5_SIGNATURE || Stream == STREAM_SHA1_SIGNATURE) {
       fname = p;
       if (jcr->FileIndex != FileIndex) {    
-         Jmsg(jcr, M_WARNING, 0, "Got MD5 but not same File as attributes\n");
+         Jmsg(jcr, M_WARNING, 0, "Got MD5/SHA1 but not same File as attributes\n");
       } else {
-        /* Update MD5 signature in catalog */
-        char MD5buf[50];           /* 24 bytes should be enough */
-        bin_to_base64(MD5buf, fname, 16);
-         Dmsg2(190, "MD5len=%d MD5=%s\n", strlen(MD5buf), MD5buf);
-        if (!db_add_MD5_to_file_record(jcr, jcr->db, jcr->FileId, MD5buf)) {
-            Jmsg(jcr, M_ERROR, 0, _("Catalog error updating MD5. %s"), 
+        /* Update signature in catalog */
+        char SIGbuf[50];           /* 24 bytes should be enough */
+        int len, type;
+        if (Stream == STREAM_MD5_SIGNATURE) {
+           len = 16;
+           type = MD5_SIG;
+        } else {
+           len = 20;
+           type = SHA1_SIG;
+        }
+        bin_to_base64(SIGbuf, fname, len);
+         Dmsg3(190, "SIGlen=%d SIG=%s type=%d\n", strlen(SIGbuf), SIGbuf, Stream);
+        if (!db_add_SIG_to_file_record(jcr, jcr->db, jcr->FileId, SIGbuf, type)) {
+            Jmsg(jcr, M_ERROR, 0, _("Catalog error updating MD5/SHA1. %s"), 
               db_strerror(jcr->db));
         }
       }
index c0ec70f10c26a7eb4002f1c7038ad67c1428a8f0..136b4e25a20b680f5a4786fe4784c029e9c0687c 100644 (file)
@@ -189,6 +189,18 @@ static struct res_items job_items[] = {
    {NULL, NULL, NULL, 0, 0, 0} 
 };
 
+/* FileOptions resource
+ *
+ *   name         handler     value                 code flags    default_value
+ */
+static struct res_items fo_items[] = {
+   {"name",        store_name, ITEM(res_fo.hdr.name), 0, ITEM_REQUIRED, 0},
+   {"description", store_str,  ITEM(res_fo.hdr.desc), 0, 0, 0},
+   {"replace",     store_replace, ITEM(res_fo.replace), REPLACE_ALWAYS, ITEM_DEFAULT, 0},
+   {NULL,         NULL,       NULL,                  0, 0, 0} 
+};
+
+
 /* FileSet resource
  *
  *   name         handler     value                 code flags    default_value
@@ -278,6 +290,7 @@ struct s_res resources[] = {
    {"storage",       store_items, R_STORAGE,   NULL},
    {"catalog",       cat_items,   R_CATALOG,   NULL},
    {"schedule",      sch_items,   R_SCHEDULE,  NULL},
+   {"fileoptions",   fo_items,    R_FILEOPTIONS, NULL},
    {"fileset",       fs_items,    R_FILESET,   NULL},
    {"group",         group_items, R_GROUP,     NULL},
    {"pool",          pool_items,  R_POOL,      NULL},
@@ -384,6 +397,7 @@ struct s_fs_opt {
 /* Options permitted for each keyword and resulting value */
 static struct s_fs_opt FS_options[] = {
    {"md5",      INC_KW_SIGNATURE,    "M"},
+   {"sha1",     INC_KW_SIGNATURE,    "S"},
    {"gzip",     INC_KW_COMPRESSION,  "Z6"},
    {"gzip1",    INC_KW_COMPRESSION,  "Z1"},
    {"gzip2",    INC_KW_COMPRESSION,  "Z2"},
@@ -1333,7 +1347,7 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass)
            case T_IDENTIFIER:
            case T_UNQUOTED_STRING:
            case T_QUOTED_STRING:
-              fname = (char *) malloc(lc->str_len + inc_opts_len + 1);
+              fname = (char *)malloc(lc->str_len + inc_opts_len + 1);
               strcpy(fname, inc_opts);
               strcat(fname, lc->str);
               if (res_all.res_fs.have_MD5) {
@@ -1355,9 +1369,9 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass)
                  if (res_all.res_fs.num_excludes == res_all.res_fs.exclude_size) {
                     res_all.res_fs.exclude_size += 10;
                     if (res_all.res_fs.exclude_array == NULL) {
-                       res_all.res_fs.exclude_array = (char **) malloc(sizeof(char *) * res_all.res_fs.exclude_size);
+                       res_all.res_fs.exclude_array = (char **)malloc(sizeof(char *) * res_all.res_fs.exclude_size);
                     } else {
-                       res_all.res_fs.exclude_array = (char **) realloc(res_all.res_fs.exclude_array,
+                       res_all.res_fs.exclude_array = (char **)realloc(res_all.res_fs.exclude_array,
                           sizeof(char *) * res_all.res_fs.exclude_size);
                     }
                  }
index d72a1b6319a240cccd55e1306a2249aee542fe46..c76ef353ece9b19bf8a266e480cc7e8c92bbf266 100644 (file)
@@ -6,7 +6,7 @@
  *    Version $Id$
  */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 2002 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -180,6 +180,24 @@ struct s_res_job {
 };
 typedef struct s_res_job JOB;
 
+/*
+ * File Options Resource (options for Includes)
+ */
+struct s_res_fo {
+   RES  hdr;
+
+   char opts[20];                     /* Options string */
+   int  replace;                      /* How (overwrite, ...) */
+   struct s_applyto *applyto;         /* applyto strings */
+}; 
+typedef struct s_res_fo FILEOPTIONS;
+
+struct s_incexc_item {
+   char opts[20];                     /* options string */
+   struct s_res_fo *fileopts;         /* file options */
+   char name[1];                      /* include/exclude name */
+};
+
 /* 
  *   FileSet Resource
  *
@@ -187,6 +205,7 @@ typedef struct s_res_job JOB;
 struct s_res_fs {
    RES   hdr;
 
+   /* ***FIXME*** each include must have chain of FileOptions */
    char **include_array;
    int num_includes;
    int include_size;
@@ -195,22 +214,11 @@ struct s_res_fs {
    int exclude_size;
    int have_MD5;                      /* set if MD5 initialized */
    struct MD5Context md5c;            /* MD5 of include/exclude */
-   char MD5[50];                      /* base 64 representation of MD5 */
+   char MD5[30];                      /* base 64 representation of MD5 */
 };
 typedef struct s_res_fs FILESET;
 
-/*
- * FileOptions Resource (options for Includes)
- */
-struct s_res_fo {
-   RES  hdr;
-
-   char opts[50];                     /* Options string */
-   struct s_applyto *applyto;         /* applyto strings */
-}; 
-typedef struct s_res_fo FILEOPTIONS;
  
-
 /* 
  *   Schedule Resource
  *
index fdeecd0cef5955390ed1cddf54a4c4776a463b00..421f7b8c9c6f4c9abc263bfd3105e806168392e5 100644 (file)
@@ -270,11 +270,11 @@ int get_attributes_and_put_in_catalog(JCR *jcr)
       long file_index;
       int stream, len;
       char *attr, *p, *fn;
-      char Opts_MD5[MAXSTRING];      /* either Verify opts or MD5 signature */
-      char MD5[MAXSTRING];
+      char Opts_SIG[MAXSTRING];      /* either Verify opts or MD5/SHA1 signature */
+      char SIG[MAXSTRING];
 
       jcr->fname = check_pool_memory_size(jcr->fname, fd->msglen);
-      if ((len = sscanf(fd->msg, "%ld %d %s", &file_index, &stream, Opts_MD5)) != 3) {
+      if ((len = sscanf(fd->msg, "%ld %d %s", &file_index, &stream, Opts_SIG)) != 3) {
          Jmsg(jcr, M_FATAL, 0, _("<filed: bad attributes, expected 3 fields got %d\n\
 msglen=%d msg=%s\n"), len, fd->msglen, fd->msg);
         set_jcr_job_status(jcr, JS_ErrorTerminated);
@@ -285,7 +285,7 @@ msglen=%d msg=%s\n"), len, fd->msglen, fd->msg);
       skip_spaces(&p);
       skip_nonspaces(&p);            /* skip Stream */
       skip_spaces(&p);
-      skip_nonspaces(&p);            /* skip Opts_MD5 */   
+      skip_nonspaces(&p);            /* skip Opts_SHA1 */   
       p++;                           /* skip space */
       fn = jcr->fname;
       while (*p != 0) {
@@ -316,16 +316,17 @@ msglen=%d msg=%s\n"), len, fd->msglen, fd->msg);
            continue;
         }
         jcr->FileId = ar.FileId;
-      } else if (stream == STREAM_MD5_SIGNATURE) {
+      } else if (stream == STREAM_MD5_SIGNATURE || stream == STREAM_SHA1_SIGNATURE) {
         if (jcr->FileIndex != (uint32_t)file_index) {
-            Jmsg2(jcr, M_ERROR, 0, _("MD5 index %d not same as attributes %d\n"),
+            Jmsg2(jcr, M_ERROR, 0, _("MD5/SHA1 index %d not same as attributes %d\n"),
               file_index, jcr->FileIndex);
            set_jcr_job_status(jcr, JS_Error);
            continue;
         }
-        db_escape_string(MD5, Opts_MD5, strlen(Opts_MD5));
-         Dmsg2(120, "MD5len=%d MD5=%s\n", strlen(MD5), MD5);
-        if (!db_add_MD5_to_file_record(jcr, jcr->db, jcr->FileId, MD5)) {
+        db_escape_string(SIG, Opts_SIG, strlen(Opts_SIG));
+         Dmsg2(120, "SIGlen=%d SIG=%s\n", strlen(SIG), SIG);
+        if (!db_add_SIG_to_file_record(jcr, jcr->db, jcr->FileId, SIG, 
+                  stream==STREAM_MD5_SIGNATURE?MD5_SIG:SHA1_SIG)) {
             Jmsg1(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
            set_jcr_job_status(jcr, JS_Error);
         }
index 027e30af5c31e530bf0ccb24b248d0126adaa533..cc62515d0e5500663ab70e67cc962d7f9b943ad6 100644 (file)
@@ -377,7 +377,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
    int stat = JS_Terminated;
    char buf[MAXSTRING];
    POOLMEM *fname = get_pool_memory(PM_MESSAGE);
-   int do_MD5 = FALSE;
+   int do_SIG = NO_SIG;
    long file_index = 0;
 
    memset(&fdbr, 0, sizeof(FILE_DBR));
@@ -387,11 +387,11 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
    
    Dmsg0(20, "bdird: waiting to receive file attributes\n");
    /*
-    * Get Attributes and MD5 Signature from File daemon
+    * Get Attributes and Signature from File daemon
     * We expect:
     *  FileIndex
     *  Stream
-    *  Options or MD5
+    *  Options or SIG (MD5/SHA1)
     *  Filename
     *  Attributes
     *  Link name  ???
@@ -399,23 +399,28 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
    while ((n=bget_msg(fd, 0)) >= 0 && !job_cancelled(jcr)) {
       int stream;
       char *attr, *p, *fn;
-      char Opts_MD5[MAXSTRING];        /* Verify Opts or MD5 signature */
+      char Opts_SIG[MAXSTRING];        /* Verify Opts or MD5/SHA1 signature */
 
       fname = check_pool_memory_size(fname, fd->msglen);
       jcr->fname = check_pool_memory_size(jcr->fname, fd->msglen);
-      Dmsg1(400, "Atts+MD5=%s\n", fd->msg);
+      Dmsg1(400, "Atts+SIG=%s\n", fd->msg);
       if ((len = sscanf(fd->msg, "%ld %d %100s", &file_index, &stream, 
-           Opts_MD5)) != 3) {
+           fname)) != 3) {
          Jmsg3(jcr, M_FATAL, 0, _("bird<filed: bad attributes, expected 3 fields got %d\n\
  mslen=%d msg=%s\n"), len, fd->msglen, fd->msg);
         goto bail_out;
       }
+      /*
+       * We read the Options or Signature into fname                               
+       *  to prevent overrun, now copy it to proper location.
+       */
+      bstrncpy(Opts_SIG, fname, sizeof(Opts_SIG));
       p = fd->msg;
       skip_nonspaces(&p);            /* skip FileIndex */
       skip_spaces(&p);
       skip_nonspaces(&p);            /* skip Stream */
       skip_spaces(&p);
-      skip_nonspaces(&p);            /* skip Opts_MD5 */   
+      skip_nonspaces(&p);            /* skip Opts_SIG */   
       p++;                           /* skip space */
       fn = fname;
       while (*p != 0) {
@@ -431,7 +436,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
         jcr->JobFiles++;
         jcr->FileIndex = file_index;    /* remember attribute file_index */
         decode_stat(attr, &statf);  /* decode file stat packet */
-        do_MD5 = FALSE;
+        do_SIG = NO_SIG;
         jcr->fn_printed = FALSE;
         strcpy(jcr->fname, fname);  /* move filename into JCR */
 
@@ -456,13 +461,13 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
         }
 
          Dmsg3(400, "Found %s in catalog. inx=%d Opts=%s\n", jcr->fname, 
-           file_index, Opts_MD5);
+           file_index, Opts_SIG);
         decode_stat(fdbr.LStat, &statc); /* decode catalog stat */
         /*
          * Loop over options supplied by user and verify the
          * fields he requests.
          */
-        for (p=Opts_MD5; *p; p++) {
+        for (p=Opts_SIG; *p; p++) {
            char ed1[30], ed2[30];
            switch (*p) {
             case 'i':                /* compare INODEs */
@@ -547,7 +552,10 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
               break;
             case '5':                /* compare MD5 */
                Dmsg1(500, "set Do_MD5 for %s\n", jcr->fname);
-              do_MD5 = TRUE;
+              do_SIG = MD5_SIG;
+              break;
+            case '1':                 /* compare SHA1 */
+              do_SIG = SHA1_SIG;
               break;
             case ':':
             case 'V':
@@ -556,32 +564,34 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
            }
         }
       /*
-       * Got MD5 Signature from Storage daemon
-       *  It came across in the Opts_MD5 field.
+       * Got SIG Signature from Storage daemon
+       *  It came across in the Opts_SIG field.
        */
-      } else if (stream == STREAM_MD5_SIGNATURE) {
-         Dmsg2(400, "stream=MD5 inx=%d MD5=%s\n", file_index, Opts_MD5);
+      } else if (stream == STREAM_MD5_SIGNATURE || stream == STREAM_SHA1_SIGNATURE) {
+         Dmsg2(400, "stream=SIG inx=%d SIG=%s\n", file_index, Opts_SIG);
         /* 
-         * When ever we get an MD5 signature is MUST have been
+         * When ever we get a signature is MUST have been
          * preceded by an attributes record, which sets attr_file_index
          */
         if (jcr->FileIndex != (uint32_t)file_index) {
-            Jmsg2(jcr, M_FATAL, 0, _("MD5 index %d not same as attributes %d\n"),
+            Jmsg2(jcr, M_FATAL, 0, _("MD5/SHA1 index %d not same as attributes %d\n"),
               file_index, jcr->FileIndex);
            goto bail_out;
         } 
-        if (do_MD5) {
-           db_escape_string(buf, Opts_MD5, strlen(Opts_MD5));
-           if (strcmp(buf, fdbr.MD5) != 0) {
+        if (do_SIG) {
+           db_escape_string(buf, Opts_SIG, strlen(Opts_SIG));
+           if (strcmp(buf, fdbr.SIG) != 0) {
               prt_fname(jcr);
               if (debug_level >= 10) {
-                  Jmsg(jcr, M_INFO, 0, _("      MD5 not same. File=%s Cat=%s\n"), buf, fdbr.MD5);
+                  Jmsg(jcr, M_INFO, 0, _("      %s not same. File=%s Cat=%s\n"), 
+                       stream==STREAM_MD5_SIGNATURE?"MD5":"SHA1", buf, fdbr.SIG);
               } else {
-                  Jmsg(jcr, M_INFO, 0, _("      MD5 differs.\n"));
+                  Jmsg(jcr, M_INFO, 0, _("      %s differs.\n"), 
+                       stream==STREAM_MD5_SIGNATURE?"MD5":"SHA1");
               }
               stat = JS_Differences;
            }
-           do_MD5 = FALSE;
+           do_SIG = FALSE;
         }
       }
       jcr->JobFiles = file_index;
index 4d7e0092291b6d409ad0d75c9cc63d16a1229962..75a5da3e0222f69b299a33267bcba9a31608010c 100644 (file)
@@ -99,8 +99,10 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
    char attribsEx[MAXSTRING];
    int stat, stream; 
    struct MD5Context md5c;
+   struct SHA1Context sha1c;
    int gotMD5 = 0;
-   unsigned char signature[16];
+   int gotSHA1 = 0;
+   unsigned char signature[25];       /* large enough for either signature */
    BSOCK *sd;
    JCR *jcr = (JCR *)ijcr;
    POOLMEM *msgsave;
@@ -312,6 +314,8 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
 
       if (ff_pkt->flags & FO_MD5) {
         MD5Init(&md5c);
+      } else if (ff_pkt->flags & FO_SHA1) {
+        SHA1Init(&sha1c);
       }
 
       /*
@@ -348,6 +352,9 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
         if (ff_pkt->flags & FO_MD5) {
            MD5Update(&md5c, (unsigned char *)rbuf, sd->msglen);
            gotMD5 = 1;
+        } else if (ff_pkt->flags & FO_SHA1) {
+           SHA1Update(&sha1c, (unsigned char *)rbuf, sd->msglen);
+           gotSHA1 = 1;
         }
 
 #ifdef HAVE_LIBZ
@@ -422,6 +429,18 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
       sd->msglen = 16;
       bnet_send(sd);
       bnet_sig(sd, BNET_EOD);        /* end of MD5 */
+#endif
+      gotMD5 = 0;
+   } else if (gotSHA1 && ff_pkt->flags & FO_SHA1) {
+   /* Terminate any SHA1 signature and send it to Storage daemon and the Director */
+      SHA1Final(&sha1c, signature);
+#ifndef NO_FD_SEND_TEST
+      bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_SHA1_SIGNATURE);
+      Dmsg1(100, "bfiled>stored:header %s\n", sd->msg);
+      memcpy(sd->msg, signature, 20);
+      sd->msglen = 20;
+      bnet_send(sd);
+      bnet_sig(sd, BNET_EOD);        /* end of SHA1 */
 #endif
       gotMD5 = 0;
    }
index 206cf33f2783985cb00e5ec24553584b88838e0a..7447678834d8df0dc60f843f53b1710d6d9feb1d 100644 (file)
@@ -90,7 +90,7 @@ void do_restore(JCR *jcr)
     *  2. Stream data
     *       a. Attributes (Unix or Win32)
     *   or  b. File data for the file
-    *   or  c. Possibly MD5 record
+    *   or  c. Possibly MD5 or SHA1 record
     *  3. Repeat step 1
     */
    while (bnet_recv(sd) >= 0 && !job_cancelled(jcr)) {
@@ -365,7 +365,7 @@ void do_restore(JCR *jcr)
         set_attributes(jcr, fname, ofile, lname, type, stream, 
                        &statp, attribsEx, &ofd);
         extract = FALSE;
-      } else if (stream != STREAM_MD5_SIGNATURE) {
+      } else if (!(stream == STREAM_MD5_SIGNATURE || stream == STREAM_SHA1_SIGNATURE)) {
          Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
       }
    }
index 410eaaa58c67ca0294548c5fa7cff597bb8415d7..20214f086d088407498ec8b5c107d0a52d3f9073 100644 (file)
@@ -61,7 +61,7 @@ void do_verify(JCR *jcr)
 /* 
  * Called here by find() for each file.
  *
- *  Find the file, compute the MD5 and send it back to the Director
+ *  Find the file, compute the MD5 or SHA1 and send it back to the Director
  */
 static int verify_file(FF_PKT *ff_pkt, void *pkt) 
 {
@@ -69,7 +69,8 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt)
    int32_t n;
    int fid, stat;
    struct MD5Context md5c;
-   unsigned char signature[20];
+   struct SHA1Context sha1c;
+   unsigned char signature[25];       /* large enough for either */
    BSOCK *dir;
    JCR *jcr = (JCR *)pkt;
 
@@ -189,10 +190,8 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt)
 
    /* If file opened, compute MD5 */
    if (fid >= 0  && ff_pkt->flags & FO_MD5) {
-      char MD5buf[50];               /* 24 should do */
-
+      char MD5buf[40];               /* 24 should do */
       MD5Init(&md5c);
-
       while ((n=read(fid, jcr->big_buf, jcr->buf_size)) > 0) {
         MD5Update(&md5c, ((unsigned char *) jcr->big_buf), n);
         jcr->JobBytes += n;
@@ -201,7 +200,6 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt)
          Jmsg(jcr, M_WARNING, -1, _("Error reading file %s: ERR=%s\n"), 
              ff_pkt->fname, strerror(errno));
       }
-
       MD5Final(signature, &md5c);
 
       bin_to_base64(MD5buf, (char *)signature, 16); /* encode 16 bytes */
@@ -209,6 +207,24 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt)
       bnet_fsend(dir, "%d %d %s *MD5-%d*", jcr->JobFiles, STREAM_MD5_SIGNATURE, MD5buf,
         jcr->JobFiles);
       Dmsg2(20, "bfiled>bdird: MD5 len=%d: msg=%s\n", dir->msglen, dir->msg);
+   } else if (fid >= 0 && ff_pkt->flags & FO_SHA1) {
+      char SHA1buf[40];              /* 24 should do */
+      SHA1Init(&sha1c);
+      while ((n=read(fid, jcr->big_buf, jcr->buf_size)) > 0) {
+        SHA1Update(&sha1c, ((unsigned char *) jcr->big_buf), n);
+        jcr->JobBytes += n;
+      }
+      if (n < 0) {
+         Jmsg(jcr, M_WARNING, -1, _("Error reading file %s: ERR=%s\n"), 
+             ff_pkt->fname, strerror(errno));
+      }
+      SHA1Final(&sha1c, signature);
+
+      bin_to_base64(SHA1buf, (char *)signature, 20); /* encode 20 bytes */
+      Dmsg2(400, "send inx=%d SHA1=%s\n", jcr->JobFiles, SHA1buf);
+      bnet_fsend(dir, "%d %d %s *SHA1-%d*", jcr->JobFiles, STREAM_SHA1_SIGNATURE, 
+        SHA1buf, jcr->JobFiles);
+      Dmsg2(20, "bfiled>bdird: SHA1 len=%d: msg=%s\n", dir->msglen, dir->msg);
    }
    if (fid >= 0) {
       close(fid);
index fff1f556d9b1befe52e1ee030fd7b6c1f6091c27..59f7a7533be450e2536e2be92dd71590643a739d 100644 (file)
@@ -213,7 +213,15 @@ void do_verify_volume(JCR *jcr)
            jcr->JobFiles);
          Dmsg2(20, "bfiled>bdird: MD5 len=%d: msg=%s\n", dir->msglen, dir->msg);
   
-      } else if (stream != STREAM_MD5_SIGNATURE) {
+      /* If SHA1 stream */
+      } else if (stream == STREAM_SHA1_SIGNATURE) {
+        char SHA1buf[30];
+        bin_to_base64(SHA1buf, (char *)sd->msg, 20); /* encode 20 bytes */
+         Dmsg2(400, "send inx=%d SHA1=%s\n", jcr->JobFiles, SHA1buf);
+         bnet_fsend(dir, "%d %d %s *SHA1-%d*", jcr->JobFiles, STREAM_SHA1_SIGNATURE, 
+           SHA1buf, jcr->JobFiles);
+         Dmsg2(20, "bfiled>bdird: SHA1 len=%d: msg=%s\n", dir->msglen, dir->msg);
+      } else {
          Pmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
       }
    }
index 38e84430fe7aac91bb0ad6cf2f88b6b566a71c04..00c17cb49b7a048d0ea95c689787f3e6f9c9265a 100755 (executable)
@@ -84,6 +84,7 @@
 #define FO_IF_NEWER     0x020         /* replace if newer */
 #define FO_NOREPLACE    0x040         /* never replace */
 #define FO_READFIFO     0x080         /* read data from fifo */
+#define FO_SHA1         0x100         /* Do SHA1 checksum */
 
 /*
  * Options saved in "options" of include list
 #define OPT_replace_if_newer  0x20    /* replace file if newer */
 #define OPT_never_replace     0x40    /* never replace */
 #define OPT_read_fifo         0x80    /* read data from fifo (named pipe) */
+#define OPT_compute_SHA1     0x100    /* compute SHA1 of file's data */
 
 
 struct s_included_file {
index b22d2883b3919d905e75243145654d5925da2d67..fcb59daa0d778e1c05c789b6e8e34ff6e5bbc519 100644 (file)
@@ -115,6 +115,9 @@ void add_fname_to_include_list(FF_PKT *ff, int prefixed, char *fname)
             case 'M':                 /* MD5 */
               inc->options |= OPT_compute_MD5;
               break;
+            case 'S':
+              inc->options |= OPT_compute_SHA1;
+              break;
             case 'n':
               inc->options |= OPT_never_replace;
               break;
index 3429ff9c105997014206d1280e13ac860b6a01dc..58a4aec748df10c315fe75bc4e53a2f683c2aba1 100644 (file)
@@ -36,7 +36,7 @@ LIBSRCS = alloc.c base64.c bmisc.c bnet.c bnet_server.c \
          cram-md5.c crc32.c daemon.c edit.c fnmatch.c \
          hmac.c idcache.c jcr.c lex.c  \
          md5.c message.c mem_pool.c parse_conf.c \
-         queue.c rwlock.c serial.c \
+         queue.c rwlock.c serial.c sha1.c \
          signal.c smartall.c tree.c util.c watchdog.c workq.c  
 
 #        immortal.c filesys.c
@@ -46,7 +46,7 @@ LIBOBJS = alloc.o base64.o bmisc.o bnet.o bnet_server.o \
          cram-md5.o crc32.o daemon.o edit.o fnmatch.o \
          hmac.o idcache.o jcr.o lex.o  \
          md5.o message.o mem_pool.o parse_conf.o \
-         queue.o rwlock.o serial.o \
+         queue.o rwlock.o serial.o sha1.o \
          signal.o smartall.o tree.o util.o watchdog.o workq.o
 
 #        immortal.o filesys.o
@@ -107,7 +107,7 @@ uninstall:
 
 clean:
        $(RMF) *.a core a.out *.o *.bak *.tex *.pdf *~ *.intpro *.extpro 1 2 3
-       $(RMF) rwlock_test
+       $(RMF) rwlock_test md5 sha1
 
 realclean: clean
        $(RMF) tags
index b36100dc03109066539d0d781ecda9129da35015..b9bd67283051acb5006e3ccf7a6fdcdf1a0defc8 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -45,6 +45,7 @@
 #include "fnmatch.h"
 #endif
 #include "md5.h"
+#include "sha1.h"
 #include "tree.h"
 #include "watchdog.h"
 #include "bpipe.h"
index ec48a43ee4303e1db36fae90dd3948d88d2d8275..f5a68abc1c781ec57004e5ba055f4c3aaa553ac5 100644 (file)
@@ -249,3 +249,36 @@ void MD5Transform(uint32_t buf[4], uint32_t in[16])
     buf[2] += c;
     buf[3] += d;
 }
+
+#ifdef MD5_SUM
+/*
+ * Reads a single ASCII file and prints the HEX md5 sum.
+ */
+#include <stdio.h>
+int main(int argc, char *argv[]) 
+{
+   FILE *fd;
+   MD5Context ctx;
+   char buf[5000];
+   char signature[20];
+
+   if (argc < 1) {
+      printf("Must have filename\n");
+      exit(1);
+   }
+   fd = fopen(argv[1], "r");
+   if (!fd) {
+      printf("Could not open %s: ERR=%s\n", argv[1], strerror(errno));
+      exit(1);
+   }
+   MD5Init(&ctx);
+   while (fgets(buf, sizeof(buf), fd)) {
+      MD5Update(&ctx, (unsigned char *)buf, strlen(buf));
+   }
+   MD5Final((unsigned char *)signature, &ctx);
+   for (int i=0; i < 16; i++) {
+      printf("%02x", signature[i]& 0xFF);
+   }
+   printf("  %s\n", argv[1]);
+}
+#endif
index 78877489bbd74d3c8fbdc92b31e583faa91f16c5..1d4ed9c95d7de0aa09bc0540f38e6e7b8e1821d7 100644 (file)
                (((word) << (bits)) | ((word) >> (32-(bits))))
 
 /* Local Function Prototyptes */
-void SHA1PadMessage(SHA1Context *);
-void SHA1ProcessMessageBlock(SHA1Context *);
+static void SHA1PadMessage(SHA1Context *);
+static void SHA1ProcessMessageBlock(SHA1Context *);
 
 /*
- *  SHA1Reset
+ *  SHA1Init
  *
  *  Description:
  *     This function will initialize the SHA1Context in preparation
@@ -57,7 +57,7 @@ void SHA1ProcessMessageBlock(SHA1Context *);
  *     sha Error Code.
  *
  */
-int SHA1Reset(SHA1Context *context)
+int SHA1Init(SHA1Context *context)
 {
     if (!context)
     {
@@ -81,7 +81,7 @@ int SHA1Reset(SHA1Context *context)
 }
 
 /*
- *  SHA1Result
+ *  SHA1Final
  *
  *  Description:
  *     This function will return the 160-bit message digest into the
@@ -99,26 +99,22 @@ int SHA1Reset(SHA1Context *context)
  *     sha Error Code.
  *
  */
-int SHA1Result( SHA1Context *context,
-               uint8_t Message_Digest[SHA1HashSize])
+int SHA1Final(SHA1Context *context,
+             uint8_t Message_Digest[SHA1HashSize])
 {
     int i;
 
-    if (!context || !Message_Digest)
-    {
+    if (!context || !Message_Digest) {
        return shaNull;
     }
 
-    if (context->Corrupted)
-    {
+    if (context->Corrupted) {
        return context->Corrupted;
     }
 
-    if (!context->Computed)
-    {
+    if (!context->Computed) {
        SHA1PadMessage(context);
-       for(i=0; i<64; ++i)
-       {
+       for(i=0; i<64; ++i) {
            /* message may be sensitive, clear it out */
            context->Message_Block[i] = 0;
        }
@@ -128,17 +124,16 @@ int SHA1Result( SHA1Context *context,
 
     }
 
-    for(i = 0; i < SHA1HashSize; ++i)
-    {
+    for(i = 0; i < SHA1HashSize; ++i) {
        Message_Digest[i] = context->Intermediate_Hash[i>>2]
-                           >> 8 * ( 3 - ( i &amp; 0x03 ) );
+                           >> 8 * ( 3 - ( i & 0x03 ) );
     }
 
     return shaSuccess;
 }
 
 /*
- *  SHA1Input
+ *  SHA1Update
  *
  *  Description:
  *     This function accepts an array of octets as the next portion
@@ -157,53 +152,45 @@ int SHA1Result( SHA1Context *context,
  *     sha Error Code.
  *
  */
-int SHA1Input(   SHA1Context    *context,
-                 const uint8_t  *message_array,
-                 unsigned       length)
+int SHA1Update(SHA1Context    *context,
+              const uint8_t  *message_array,
+              unsigned       length)
 {
-    if (!length)
-    {
+    if (!length) {
        return shaSuccess;
     }
 
-    if (!context || !message_array)
-    {
+    if (!context || !message_array) {
        return shaNull;
     }
 
-    if (context->Computed)
-    {
+    if (context->Computed) {
        context->Corrupted = shaStateError;
 
        return shaStateError;
     }
 
-    if (context->Corrupted)
-    {
+    if (context->Corrupted) {
         return context->Corrupted;
     }
-    while(length-- &amp;&amp; !context->Corrupted)
-    {
-    context->Message_Block[context->Message_Block_Index++] =
-                   (*message_array &amp; 0xFF);
-
-    context->Length_Low += 8;
-    if (context->Length_Low == 0)
-    {
-       context->Length_High++;
-       if (context->Length_High == 0)
-       {
-           /* Message is too long */
-           context->Corrupted = 1;
-       }
-    }
-
-    if (context->Message_Block_Index == 64)
-    {
-       SHA1ProcessMessageBlock(context);
-    }
-
-    message_array++;
+    while(length-- && !context->Corrupted) {
+       context->Message_Block[context->Message_Block_Index++] =
+                   (*message_array & 0xFF);
+
+       context->Length_Low += 8;
+       if (context->Length_Low == 0) {
+          context->Length_High++;
+          if (context->Length_High == 0) {
+              /* Message is too long */
+              context->Corrupted = 1;
+          }
+       }
+
+       if (context->Message_Block_Index == 64) {
+          SHA1ProcessMessageBlock(context);
+       }
+
+       message_array++;
     }
 
     return shaSuccess;
@@ -230,7 +217,7 @@ int SHA1Input(        SHA1Context    *context,
  *
  *
  */
-void SHA1ProcessMessageBlock(SHA1Context *context)
+static void SHA1ProcessMessageBlock(SHA1Context *context)
 {
     const uint32_t K[] =    {      /* Constants defined in SHA-1   */
                            0x5A827999,
@@ -246,16 +233,14 @@ void SHA1ProcessMessageBlock(SHA1Context *context)
     /*
      * Initialize the first 16 words in the array W
      */
-    for(t = 0; t < 16; t++)
-    {
+    for(t = 0; t < 16; t++) {
        W[t] = context->Message_Block[t * 4] << 24;
        W[t] |= context->Message_Block[t * 4 + 1] << 16;
        W[t] |= context->Message_Block[t * 4 + 2] << 8;
        W[t] |= context->Message_Block[t * 4 + 3];
     }
 
-    for(t = 16; t < 80; t++)
-    {
+    for(t = 16; t < 80; t++) {
        W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
     }
 
@@ -265,10 +250,9 @@ void SHA1ProcessMessageBlock(SHA1Context *context)
     D = context->Intermediate_Hash[3];
     E = context->Intermediate_Hash[4];
 
-    for(t = 0; t < 20; t++)
-    {
+    for(t = 0; t < 20; t++) {
        temp =  SHA1CircularShift(5,A) +
-               ((B &amp; C) | ((~B) &amp; D)) + E + W[t] + K[0];
+               ((B & C) | ((~B) & D)) + E + W[t] + K[0];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
@@ -277,8 +261,7 @@ void SHA1ProcessMessageBlock(SHA1Context *context)
        A = temp;
     }
 
-    for(t = 20; t < 40; t++)
-    {
+    for(t = 20; t < 40; t++) {
        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
        E = D;
        D = C;
@@ -287,10 +270,9 @@ void SHA1ProcessMessageBlock(SHA1Context *context)
        A = temp;
     }
 
-    for(t = 40; t < 60; t++)
-    {
+    for(t = 40; t < 60; t++) {
        temp = SHA1CircularShift(5,A) +
-              ((B &amp; C) | (B &amp; D) | (C &amp; D)) + E + W[t] + K[2];
+              ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
@@ -298,8 +280,7 @@ void SHA1ProcessMessageBlock(SHA1Context *context)
        A = temp;
     }
 
-    for(t = 60; t < 80; t++)
-    {
+    for(t = 60; t < 80; t++) {
        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
        E = D;
        D = C;
@@ -341,7 +322,7 @@ void SHA1ProcessMessageBlock(SHA1Context *context)
  *
  */
 
-void SHA1PadMessage(SHA1Context *context)
+static void SHA1PadMessage(SHA1Context *context)
 {
     /*
      * Check to see if the current message block is too small to hold
@@ -349,26 +330,20 @@ void SHA1PadMessage(SHA1Context *context)
      * block, process it, and then continue padding into a second
      * block.
      */
-    if (context->Message_Block_Index > 55)
-    {
+    if (context->Message_Block_Index > 55) {
        context->Message_Block[context->Message_Block_Index++] = 0x80;
-       while(context->Message_Block_Index < 64)
-       {
+       while(context->Message_Block_Index < 64) {
            context->Message_Block[context->Message_Block_Index++] = 0;
        }
 
        SHA1ProcessMessageBlock(context);
 
-       while(context->Message_Block_Index < 56)
-       {
+       while(context->Message_Block_Index < 56) {
            context->Message_Block[context->Message_Block_Index++] = 0;
        }
-    }
-    else
-    {
+    } else {
        context->Message_Block[context->Message_Block_Index++] = 0x80;
-       while(context->Message_Block_Index < 56)
-       {
+       while(context->Message_Block_Index < 56) {
 
            context->Message_Block[context->Message_Block_Index++] = 0;
        }
@@ -448,36 +423,31 @@ int main()
     /*
      * Perform SHA-1 tests
      */
-    for(j = 0; j < 4; ++j)
-    {
+    for(j = 0; j < 4; ++j) {
         printf( "\nTest %d: %d, '%s'\n",
                j+1,
                repeatcount[j],
                testarray[j]);
 
-       err = SHA1Reset(&amp;sha);
-       if (err)
-       {
+       err = SHA1Init(&sha);
+       if (err) {
             fprintf(stderr, "SHA1Reset Error %d.\n", err );
            break;    /* out of for j loop */
        }
 
-       for(i = 0; i < repeatcount[j]; ++i)
-       {
+       for(i = 0; i < repeatcount[j]; ++i) {
 
-           err = SHA1Input(&amp;sha,
+           err = SHA1Input(&sha,
                  (const unsigned char *) testarray[j],
                  strlen(testarray[j]));
-           if (err)
-           {
+           if (err) {
                 fprintf(stderr, "SHA1Input Error %d.\n", err );
                break;    /* out of for i loop */
            }
        }
 
-       err = SHA1Result(&amp;sha, Message_Digest);
-       if (err)
-       {
+       err = SHA1Final(&sha, Message_Digest);
+       if (err) {
            fprintf(stderr,
             "SHA1Result Error %d, could not compute message digest.\n",
            err );
@@ -485,8 +455,7 @@ int main()
        else
        {
             printf("\t");
-           for(i = 0; i < 20 ; ++i)
-           {
+           for(i = 0; i < 20 ; ++i) {
                 printf("%02X ", Message_Digest[i]);
            }
             printf("\n");
@@ -496,11 +465,44 @@ int main()
     }
 
     /* Test some error returns */
-    err = SHA1Input(&amp;sha,(const unsigned char *) testarray[1], 1);
+    err = SHA1Input(&sha,(const unsigned char *) testarray[1], 1);
     printf ("\nError %d. Should be %d.\n", err, shaStateError );
-    err = SHA1Reset(0);
+    err = SHA1Init(0);
     printf ("\nError %d. Should be %d.\n", err, shaNull );
     return 0;
 }
 
 #endif /* TEST_DRIVER */
+
+#ifdef SHA1_SUM
+/*
+ * Reads a single ASCII file and prints the HEX sha1 sum.
+ */
+#include <stdio.h>
+int main(int argc, char *argv[]) 
+{
+   FILE *fd;
+   SHA1Context ctx;
+   char buf[5000];
+   char signature[25];
+
+   if (argc < 1) {
+      printf("Must have filename\n");
+      exit(1);
+   }
+   fd = fopen(argv[1], "r");
+   if (!fd) {
+      printf("Could not open %s: ERR=%s\n", argv[1], strerror(errno));
+      exit(1);
+   }
+   SHA1Init(&ctx);
+   while (fgets(buf, sizeof(buf), fd)) {
+      SHA1Update(&ctx, (unsigned char *)buf, strlen(buf));
+   }
+   SHA1Final(&ctx, (unsigned char *)signature);
+   for (int i=0; i < 20; i++) {
+      printf("%02x", signature[i]& 0xFF);
+   }
+   printf("  %s\n", argv[1]);
+}
+#endif
index 35e53d979df37be2f933c65852cd5cd24656cd30..dc10392e22d813d415d5f70e2d8bd7dac55f561f 100644 (file)
@@ -2,15 +2,15 @@
  *  sha1.h
  *
  *  Description:
- *      This is the header file for code which implements the Secure
- *      Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
- *      April 17, 1995.
+ *     This is the header file for code which implements the Secure
+ *     Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
+ *     April 17, 1995.
  *
- *      Many of the variable names in this code, especially the
- *      single character names, were used because those were the names
- *      used in the publication.
+ *     Many of the variable names in this code, especially the
+ *     single character names, were used because those were the names
+ *     used in the publication.
  *
- *      Please read the file sha1.c for more information.
+ *     Please read the file sha1.c for more information.
  *
  * Full Copyright Statement
  *
@@ -55,9 +55,9 @@
 /*
  * If you do not have the ISO standard stdint.h header file, then you
  * must typdef the following:
- *    name              meaning
- *  uint32_t         unsigned 32 bit integer
- *  uint8_t          unsigned 8 bit integer (i.e., unsigned char)
+ *    name             meaning
+ *  uint32_t        unsigned 32 bit integer
+ *  uint8_t         unsigned 8 bit integer (i.e., unsigned char)
  *  int_least16_t    integer of >= 16 bits
  *
  */
@@ -67,9 +67,9 @@
 enum
 {
     shaSuccess = 0,
-    shaNull,            /* Null pointer parameter */
-    shaInputTooLong,    /* input data too long */
-    shaStateError       /* called Input after Result */
+    shaNull,           /* Null pointer parameter */
+    shaInputTooLong,   /* input data too long */
+    shaStateError      /* called Input after Result */
 };
 #endif
 #define SHA1HashSize 20
@@ -82,26 +82,26 @@ typedef struct SHA1Context
 {
     uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest  */
 
-    uint32_t Length_Low;            /* Message length in bits      */
-    uint32_t Length_High;           /* Message length in bits      */
+    uint32_t Length_Low;           /* Message length in bits      */
+    uint32_t Length_High;          /* Message length in bits      */
 
-                               /* Index into message block array   */
+                              /* Index into message block array   */
     int_least16_t Message_Block_Index;
-    uint8_t Message_Block[64];      /* 512-bit message blocks      */
+    uint8_t Message_Block[64];     /* 512-bit message blocks      */
 
-    int Computed;               /* Is the digest computed?         */
-    int Corrupted;             /* Is the message digest corrupted? */
+    int Computed;              /* Is the digest computed?         */
+    int Corrupted;            /* Is the message digest corrupted? */
 } SHA1Context;
 
 /*
  *  Function Prototypes
  */
 
-int SHA1Reset(  SHA1Context *);
-int SHA1Input(  SHA1Context *,
-                const uint8_t *,
-                unsigned int);
-int SHA1Result( SHA1Context *,
-                uint8_t Message_Digest[SHA1HashSize]);
+int SHA1Init(SHA1Context *);
+int SHA1Update(SHA1Context *,
+              const uint8_t *,
+              unsigned int);
+int SHA1Final(SHA1Context *,
+              uint8_t Message_Digest[SHA1HashSize]);
 
 #endif
index 2c375a2297094c906e96186e859020edb93da040..c3ea57e56081648a6f7f0bae4b2ecb29e860bb17 100644 (file)
@@ -190,7 +190,7 @@ int do_append_data(JCR *jcr)
 
         /* Send attributes and MD5 to Director for Catalog */
         if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_MD5_SIGNATURE ||
-            stream == STREAM_WIN32_ATTRIBUTES) { 
+            stream == STREAM_WIN32_ATTRIBUTES || stream == STREAM_SHA1_SIGNATURE) { 
            if (!jcr->no_attributes) {
               if (jcr->spool_attributes && jcr->dir_bsock->spool_fd) {
                  jcr->dir_bsock->spool = 1;
index 3ecadbdc569461c35b17703150eb69a0aeae9003..be9b1fa5ad8c959abab2f4f49f89bd1bd3145270 100644 (file)
@@ -467,7 +467,8 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
          Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
         prog_name_msg = 1;
       }
-   } else if (rec->Stream != STREAM_MD5_SIGNATURE) {
+   } else if (!(rec->Stream == STREAM_MD5_SIGNATURE ||
+               rec->Stream == STREAM_SHA1_SIGNATURE)) {
       Pmsg2(0, "None of above!!! stream=%d data=%s\n", rec->Stream, rec->data);
    }
 }
index e5878af641456423e1b69ac5ed1deb140be25136..ebc4977aca36e85ccb370ceda7f6542c2abd6a12 100644 (file)
@@ -50,7 +50,7 @@ static int  create_client_record(B_DB *db, CLIENT_DBR *cr);
 static int  create_fileset_record(B_DB *db, FILESET_DBR *fsr);
 static int  create_jobmedia_record(B_DB *db, JCR *jcr);
 static JCR *create_jcr(JOB_DBR *jr, DEV_RECORD *rec, uint32_t JobId);
-static int update_MD5_record(B_DB *db, char *MD5buf, DEV_RECORD *rec);
+static int update_SIG_record(B_DB *db, char *SIGbuf, DEV_RECORD *rec, int type);
 
 
 /* Global variables */
@@ -620,12 +620,21 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
 
 
    } else if (rec->Stream == STREAM_MD5_SIGNATURE) {
-      char MD5buf[30];
+      char MD5buf[50];
       bin_to_base64(MD5buf, (char *)rec->data, 16); /* encode 16 bytes */
       if (verbose > 1) {
          Pmsg1(000, _("Got MD5 record: %s\n"), MD5buf);
       }
-      update_MD5_record(db, MD5buf, rec);
+      update_SIG_record(db, MD5buf, rec, MD5_SIG);
+
+   } else if (rec->Stream == STREAM_SHA1_SIGNATURE) {
+      char SIGbuf[50];
+      bin_to_base64(SIGbuf, (char *)rec->data, 20); /* encode 20 bytes */
+      if (verbose > 1) {
+         Pmsg1(000, _("Got SHA1 record: %s\n"), SIGbuf);
+      }
+      update_SIG_record(db, SIGbuf, rec, SHA1_SIG);
+
 
    } else if (rec->Stream == STREAM_PROGRAM_NAMES) {
       if (verbose) {
@@ -1038,16 +1047,16 @@ static int create_jobmedia_record(B_DB *db, JCR *mjcr)
 }
 
 /* 
- * Simulate the database call that updates the MD5 record
+ * Simulate the database call that updates the MD5/SHA1 record
  */
-static int update_MD5_record(B_DB *db, char *MD5buf, DEV_RECORD *rec)
+static int update_SIG_record(B_DB *db, char *SIGbuf, DEV_RECORD *rec, int type)
 {
    JCR *mjcr;
 
    mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
    if (!mjcr) {
       if (mr.VolJobs > 0) {
-         Pmsg2(000, _("Could not find SessId=%d SessTime=%d for MD5 record.\n"),
+         Pmsg2(000, _("Could not find SessId=%d SessTime=%d for MD5/SHA1 record.\n"),
                      rec->VolSessionId, rec->VolSessionTime);
       } else {
         ignored_msgs++;
@@ -1060,13 +1069,13 @@ static int update_MD5_record(B_DB *db, char *MD5buf, DEV_RECORD *rec)
       return 1;
    }
    
-   if (!db_add_MD5_to_file_record(bjcr, db, mjcr->FileId, MD5buf)) {
-      Pmsg1(0, _("Could not add MD5 to File record. ERR=%s\n"), db_strerror(db));
+   if (!db_add_SIG_to_file_record(bjcr, db, mjcr->FileId, SIGbuf, type)) {
+      Pmsg1(0, _("Could not add MD5/SHA1 to File record. ERR=%s\n"), db_strerror(db));
       free_jcr(mjcr);
       return 0;
    }
    if (verbose > 1) {
-      Pmsg0(000, _("Updated MD5 record\n"));
+      Pmsg0(000, _("Updated MD5/SHA1 record\n"));
    }
    free_jcr(mjcr);
    return 1;
index e87833ae277caa9c0bb5df8d45767b760fe18e03..ab69174604768a3db0a4da25b09dc0d28e6f987a 100644 (file)
@@ -460,6 +460,12 @@ int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir)
         changer = edit_device_codes(jcr, changer, 
                       jcr->device->changer_command, "load");
         status = run_program(changer, timeout, NULL);
+        if (status == 0) {
+            Jmsg(jcr, M_INFO, 0, _("Autochanger \"load slot\" status is OK.\n"));
+        } else {
+            Jmsg(jcr, M_INFO, 0, _("Bad autochanger \"load slot\" status = %d.\n"),
+              status);
+        }
          Dmsg2(100, "load slot %d status=%d\n", slot, status);
       }
       free_pool_memory(changer);
index a78dcc6f4ac7c95c05adc5a8695c86e53b24ffde..2257a1b63ef83f2654daa8feb72c49cd89592ea9 100644 (file)
@@ -94,6 +94,8 @@ char *stream_to_ascii(int stream, int fi)
        return "DATA";
     case STREAM_MD5_SIGNATURE:
        return "MD5";
+    case STREAM_SHA1_SIGNATURE:
+       return "SHA1";
     case STREAM_GZIP_DATA:
        return "GZIP";
     case STREAM_WIN32_ATTRIBUTES:
@@ -112,6 +114,8 @@ char *stream_to_ascii(int stream, int fi)
        return "contDATA";
     case -STREAM_MD5_SIGNATURE:
        return "contMD5";
+    case -STREAM_SHA1_SIGNATURE:
+       return "contSHA1";
     case -STREAM_GZIP_DATA:
        return "contGZIP";
     case -STREAM_WIN32_ATTRIBUTES: