00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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;
00074 }
00075 else
00076 {
00077 return CompareMD5Net(file1,file2,ip);
00078 }
00079 }
00080
00081
00082
00083 int CompareBinarySums(file1,file2,ip,sstat,dstat)
00084
00085
00086
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;
00129 }
00130 else
00131 {
00132 Debug("Using network md5 checksum instead\n");
00133 return CompareMD5Net(file1,file2,ip);
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
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)
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 }