Main Page | Class List | Directories | File List | Class Members | File Members

checksums.c

Go to the documentation of this file.
00001 /* cfengine for GNU
00002  
00003         Copyright (C) 1995
00004         Free Software Foundation, Inc.
00005  
00006    This file is part of GNU cfengine - written and maintained 
00007    by Mark Burgess, Dept of Computing and Engineering, Oslo College,
00008    Dept. of Theoretical physics, University of Oslo
00009  
00010    This program is free software; you can redistribute it and/or modify it
00011    under the terms of the GNU General Public License as published by the
00012    Free Software Foundation; either version 2, or (at your option) any
00013    later version.
00014  
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019  
00020   You should have received a copy of the GNU General Public License
00021   along with this program; if not, write to the Free Software
00022   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
00023 
00024 */
00025  
00026 
00027 
00028 /*******************************************************************/
00029 /*                                                                 */
00030 /* Checksums                                                       */
00031 /*                                                                 */
00032 /*******************************************************************/
00033 
00034 #include "cf.defs.h"
00035 #include "cf.extern.h"
00036 
00037 /*******************************************************************/
00038 
00039 int CompareCheckSums(file1,file2,ip,sstat,dstat)
00040 
00041 char *file1, *file2;
00042 struct Image *ip;
00043 struct stat *sstat, *dstat;
00044 
00045 { static unsigned char digest1[EVP_MAX_MD_SIZE+1], digest2[EVP_MAX_MD_SIZE+1];
00046   int i;
00047 
00048 Debug("CompareCheckSums(%s,%s)\n",file1,file2);
00049 
00050 if (sstat->st_size != dstat->st_size)
00051    {
00052    Debug("File sizes differ, no need to compute checksum\n");
00053    return true;
00054    }
00055   
00056 Debug2("Compare checksums on %s:%s & %s\n",ip->server,file1,file2);
00057 
00058 if (strcmp(ip->server,"localhost") == 0)
00059    {
00060    ChecksumFile(file1,digest1,'m');
00061    ChecksumFile(file2,digest2,'m');
00062 
00063    for (i = 0; i < EVP_MAX_MD_SIZE; i++)
00064       {
00065       if (digest1[i] != digest2[i])
00066          {
00067          Verbose("Checksum mismatch...\n");
00068          return true;
00069          }
00070       }
00071 
00072    Debug("Files were identical\n");
00073    return false;  /* only if files are identical */
00074    }
00075 else
00076    {
00077    return CompareMD5Net(file1,file2,ip); /* client.c */
00078    }
00079 }
00080 
00081 /*******************************************************************/
00082 
00083 int CompareBinarySums(file1,file2,ip,sstat,dstat)
00084 
00085      /* See the md5 algorithms in pub-lib/md5.c */
00086      /* file 1 is source                        */
00087 
00088 char *file1, *file2;
00089 struct Image *ip;
00090 struct stat *sstat, *dstat;
00091 
00092  { int fd1, fd2,bytes1,bytes2;
00093    char buff1[BUFSIZ],buff2[BUFSIZ];
00094 
00095 Debug("CompareBinarySums(%s,%s)\n",file1,file2);
00096 
00097 if (sstat->st_size != dstat->st_size)
00098    {
00099    Debug("File sizes differ, no need to compute checksum\n");
00100    return true;
00101    }
00102   
00103 Debug2("Compare binary sums on %s:%s & %s\n",ip->server,file1,file2);
00104 
00105 if (strcmp(ip->server,"localhost") == 0)
00106    {
00107    fd1 = open(file1, O_RDONLY|O_BINARY, 0400);
00108    fd2 = open(file2, O_RDONLY|O_BINARY, 0400);
00109   
00110    do
00111       {
00112       bytes1 = read(fd1, buff1, BUFSIZ);
00113       bytes2 = read(fd2, buff2, BUFSIZ);
00114 
00115       if ((bytes1 != bytes2) || (memcmp(buff1, buff2, bytes1) != 0))
00116          {
00117          Verbose("Binary Comparison mismatch...\n");
00118          close(fd2);
00119          close(fd1);
00120          return true;
00121          }
00122       }
00123    while (bytes1 > 0);
00124   
00125    close(fd2);
00126    close(fd1);
00127 
00128    return false;  /* only if files are identical */
00129    }
00130 else
00131    {
00132    Debug("Using network md5 checksum instead\n");
00133    return CompareMD5Net(file1,file2,ip); /* client.c */
00134    }
00135 }
00136 
00137 /*******************************************************************/
00138 
00139 void ChecksumFile(filename,digest,type)
00140 
00141 char *filename,type;
00142 unsigned char digest[EVP_MAX_MD_SIZE+1];
00143 
00144 { FILE *file;
00145   EVP_MD_CTX context;
00146   int len, md_len;
00147   unsigned char buffer[1024];
00148   const EVP_MD *md = NULL;
00149 
00150 Debug2("ChecksumFile(%c,%s)\n",type,filename);
00151 
00152 if ((file = fopen (filename, "rb")) == NULL)
00153    {
00154    printf ("%s can't be opened\n", filename);
00155    }
00156 else
00157    {
00158    switch (type)
00159       {
00160       case 's': md = EVP_get_digestbyname("sha");
00161                 break;
00162       case 'm': md = EVP_get_digestbyname("md5");
00163                 break;
00164       default: FatalError("Software failure in ChecksumFile");
00165       }
00166    
00167    EVP_DigestInit(&context,md);
00168 
00169    while (len = fread(buffer,1,1024,file))
00170       {
00171       EVP_DigestUpdate(&context,buffer,len);
00172       }
00173 
00174    EVP_DigestFinal(&context,digest,&md_len);
00175    
00176    /* Digest length stored in md_len */
00177    fclose (file);
00178    }
00179 }
00180 
00181 /*******************************************************************/
00182 
00183 void ChecksumString(buffer,len,digest,type)
00184 
00185 char *buffer,type;
00186 int len;
00187 unsigned char digest[EVP_MAX_MD_SIZE+1];
00188 
00189 { EVP_MD_CTX context;
00190   const EVP_MD *md = NULL;
00191   int md_len;
00192 
00193 Debug2("ChecksumString(%c)\n",type);
00194 
00195 switch (type)
00196    {
00197    case 's': md = EVP_get_digestbyname("sha");
00198        break;
00199    case 'm': md = EVP_get_digestbyname("md5");
00200        break;
00201    default: FatalError("Software failure in ChecksumFile");
00202    }
00203  
00204 EVP_DigestInit(&context,md); 
00205 EVP_DigestUpdate(&context,(unsigned char*)buffer,len);
00206 EVP_DigestFinal(&context,digest,&md_len);
00207 }
00208 
00209 /*******************************************************************/
00210 
00211 int ChecksumsMatch(digest1,digest2,type)
00212 
00213 unsigned char digest1[EVP_MAX_MD_SIZE+1],digest2[EVP_MAX_MD_SIZE+1];
00214 char type;
00215 
00216 { int i,size = EVP_MAX_MD_SIZE;
00217  
00218 switch(type)  /* Size of message digests */
00219    {
00220    case 'm': size = CF_MD5_LEN;
00221        break;
00222    case 's': size = CF_SHA_LEN;
00223        break;
00224    }
00225 
00226 for (i = 0; i < size; i++)
00227    {
00228    if (digest1[i] != digest2[i])
00229       {
00230       return false;
00231       }
00232    }
00233 
00234 return true;
00235 }

© sourcejam.com 2005-2008