Date: 2005-08-17 Initial Package Version: 2.9.6 Origin: Christian Hamar alias krix Description: Use sha1sum() instead of md5sum() in .fdb. It is backward compatible, as it still uses md5sums() for the pacman package itself. Makefile.in | 2 scripts/gensync | 35 +++ scripts/updatesync | 33 +++ src/db.c | 9 src/md5.h | 1 src/package.c | 8 src/package.h | 1 src/pacman.c | 105 ++++++++--- src/sha1.c | 482 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/sha1.h | 108 +++++++++++ 10 files changed, 741 insertions(+), 43 deletions(-) diff -Naur pacman-2.9.6.orig/Makefile.in pacman-2.9.6/Makefile.in --- pacman-2.9.6.orig/Makefile.in 2005-08-14 21:54:23.000000000 +0200 +++ pacman-2.9.6/Makefile.in 2005-08-15 12:30:19.000000000 +0200 @@ -56,6 +56,7 @@ $(SRCDIR)pacsync.c \ $(SRCDIR)md5.c \ $(SRCDIR)md5driver.c \ + $(SRCDIR)sha1.c \ $(SRCDIR)strhash.c \ $(SRCDIR)vercmp.c \ $(SRCDIR)rpmvercmp.c @@ -69,6 +70,7 @@ $(OBJDIR)pacsync.o \ $(OBJDIR)md5.o \ $(OBJDIR)md5driver.o \ + $(OBJDIR)sha1.o \ $(OBJDIR)strhash.o \ $(OBJDIR)rpmvercmp.o diff -Naur pacman-2.9.6.orig/scripts/gensync pacman-2.9.6/scripts/gensync --- pacman-2.9.6.orig/scripts/gensync 2005-08-14 21:54:23.000000000 +0200 +++ pacman-2.9.6/scripts/gensync 2005-08-15 16:26:38.000000000 +0200 @@ -33,7 +33,7 @@ echo "from . gensync builds the database in a temporary directory" echo "and then compresses it to ." echo - echo "gensync will calculate md5sums of packages in the same directory as" + echo "gensync will calculate sha1sums of packages in the same directory as" echo ", unless an alternate [package_directory] is specified." echo echo "note: The name is important. It must be of the form" @@ -56,7 +56,7 @@ Finclude() { return 0; } -get_md5checksum() +get_md5checksum() # Need for backward compatibility { if [ "$pkgdir" != "" ]; then pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel-$arch.fpm" @@ -71,6 +71,21 @@ return 0 } +get_sha1checksum() +{ + if [ "$pkgdir" != "" ]; then + pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel-$arch.fpm" + else + pkgfile="$destdir/$pkgname-$pkgver-$pkgrel-$arch.fpm" + fi + if [ -f $pkgfile ]; then + sha1line=`sha1sum $pkgfile` + [ ! -z "$sha1line" ] && pkgsha1sum=${sha1line% *} + echo $pkgsha1sum + fi + return 0 +} + db_write_entry() { unset pkgname pkgver pkgrel pkgdesc force @@ -101,6 +116,11 @@ echo "$pkgmd5sum" >>desc echo "" >>desc fi + if [ ! -z $pkgsha1sum ]; then + echo "%SHA1SUM%" >>desc + echo "$pkgsha1sum" >>desc + echo "" >>desc + fi if [ ${#groups[*]} -gt 0 ]; then echo "%GROUPS%" >>desc for it in "${groups[@]}"; do @@ -181,7 +201,7 @@ gstmpdir=$(mktemp -d /tmp/gensync.XXXXXXXXXX) || exit 1 [ ! -d $rootdir ] && die "invalid root dir: $rootdir" -echo "gensync: building database entries, generating md5sums..." >&2 +echo "gensync: building database entries, generating sha1sums..." >&2 cd `dirname $2` for file in `find $rootdir/* -name FrugalBuild`; do unset nobuild archs @@ -196,8 +216,13 @@ fi [ -f $pkgfile ] || die "missing package file: $pkgfile" csize=`du -b $pkgfile | cut -f1` - pkgmd5sum=`get_md5checksum $pkgfile` - [ -z $pkgmd5sum ] && die "error generating checksum for $pkgfile" + if [ "$pkgname" == "pacman" ]; then + pkgmd5sum=`get_md5checksum $pkgfile` + [ -z $pkgmd5sum ] && die "error generating md5 checksum for $pkgfile" + else + pkgsha1sum=`get_sha1checksum $pkgfile` + [ -z $pkgsha1sum ] && die "error generating sha1 checksum for $pkgfile" + fi db_write_entry $file [ $? -gt 0 ] && die "error writing entry for $file" done diff -Naur pacman-2.9.6.orig/scripts/updatesync pacman-2.9.6/scripts/updatesync --- pacman-2.9.6.orig/scripts/updatesync 2005-08-14 21:54:23.000000000 +0200 +++ pacman-2.9.6/scripts/updatesync 2005-08-15 16:28:36.000000000 +0200 @@ -41,7 +41,7 @@ echo "del - Will remove a package's entry from the db." echo " It takes the package's name as an option." echo - echo "updatesync will calculate md5sums of packages in the same directory as" + echo "updatesync will calculate sha1sums of packages in the same directory as" echo ", unless an alternate [package_directory] is specified." echo echo "example: updatesync upd /home/mypkgs/custom.fdb FrugalBuild" @@ -59,7 +59,7 @@ Finclude() { return 0; } -get_md5checksum() +get_md5checksum() # For backward compatibility (Need to md5sum the pacman package) { if [ "$pkgdir" != "" ]; then pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel-$arch.fpm" @@ -74,6 +74,21 @@ return 0 } +get_sha1checksum() +{ + if [ "$pkgdir" != "" ]; then + pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel-$arch.fpm" + else + pkgfile="$destdir/$pkgname-$pkgver-$pkgrel-$arch.fpm" + fi + if [ -f $pkgfile ]; then + sha1line=`sha1sum $pkgfile` + [ ! -z "$sha1line" ] && pkgsha1sum=${sha1line% *} + echo $pkgsha1sum + fi + return 0 +} + db_write_entry() { unset pkgname pkgver pkgrel pkgdesc force @@ -104,6 +119,11 @@ echo "$pkgmd5sum" >>desc echo "" >>desc fi + if [ ! -z $pkgsha1sum ]; then + echo "%SHA1SUM%" >>desc + echo "$pkgsha1sum" >>desc + echo "" >>desc + fi if [ ${#groups[*]} -gt 0 ]; then echo "%GROUPS%" >>desc for it in "${groups[@]}"; do @@ -221,8 +241,13 @@ fi [ -f $pkgfile ] || die "missing package file: $pkgfile" csize=`du -b $pkgfile | cut -f1` - pkgmd5sum=`get_md5checksum $pkgfile` - [ -z $pkgmd5sum ] && die "error generating checksum for $pkgfile" + if [ "$pkgname" == "pacman" ]; then + pkgmd5sum=`get_md5checksum $pkgfile` + [ -z $pkgmd5sum ] && die "error generating md5 checksum for $pkgfile" + else + pkgsha1sum=`get_sha1checksum $pkgfile` + [ -z $pkgsha1sum ] && die "error generating sha1 checksum for $pkgfile" + fi echo "updatesync: creating entry for $option" >&2 db_write_entry $option || die "error writing entry for $option" fi diff -Naur pacman-2.9.6.orig/src/db.c pacman-2.9.6/src/db.c --- pacman-2.9.6.orig/src/db.c 2005-08-14 21:54:23.000000000 +0200 +++ pacman-2.9.6/src/db.c 2005-08-15 14:34:37.000000000 +0200 @@ -396,7 +396,14 @@ } else if(!strcmp(line, "%MD5SUM%")) { /* MD5SUM tag only appears in sync repositories, * not the local one. */ - if(fgets(info->md5sum, sizeof(info->md5sum), fp) == NULL) { + if((fgets(info->md5sum, sizeof(info->md5sum), fp) == NULL)) { + FREEPKG(info); + return(NULL); + } + } else if(!strcmp(line, "%SHA1SUM%")) { + /* SHA1SUM tag only appears in sync repositories, + * not the local one. */ + if((fgets(info->sha1sum, sizeof(info->sha1sum), fp) == NULL)) { FREEPKG(info); return(NULL); } diff -Naur pacman-2.9.6.orig/src/package.c pacman-2.9.6/src/package.c --- pacman-2.9.6.orig/src/package.c 2005-08-14 21:54:23.000000000 +0200 +++ pacman-2.9.6/src/package.c 2005-08-15 14:27:47.000000000 +0200 @@ -262,6 +262,7 @@ pkg->installdate[0] = '\0'; pkg->packager[0] = '\0'; pkg->md5sum[0] = '\0'; + pkg->sha1sum[0] = '\0'; pkg->arch[0] = '\0'; pkg->size = 0; pkg->scriptlet = 0; @@ -421,7 +423,11 @@ printf("Size (compressed) : %ld\n", info->size); printf("Description : "); indentprint(info->desc, 20); - printf("\nMD5 Sum : %s\n", info->md5sum); + if (info->md5sum[0] != '\0' && info->md5sum != NULL) { + printf("\nMD5 Sum : %s\n", info->md5sum); + } else if (info->sha1sum[0] != '\0' && info->sha1sum != NULL) { + printf("\nSHA1 Sum : %s\n", info->sha1sum); + } } int split_pkgname(char *pkgfile, char *name, char *version) diff -Naur pacman-2.9.6.orig/src/package.h pacman-2.9.6/src/package.h --- pacman-2.9.6.orig/src/package.h 2005-08-14 21:54:23.000000000 +0200 +++ pacman-2.9.6/src/package.h 2005-08-14 22:45:51.000000000 +0200 @@ -55,6 +55,7 @@ char installdate[32]; char packager[64]; char md5sum[33]; + char sha1sum[41]; char arch[32]; unsigned long size; unsigned short scriptlet; diff -Naur pacman-2.9.6.orig/src/pacman.c pacman-2.9.6/src/pacman.c --- pacman-2.9.6.orig/src/pacman.c 2005-08-14 21:54:23.000000000 +0200 +++ pacman-2.9.6/src/pacman.c 2005-08-15 16:20:53.000000000 +0200 @@ -40,6 +40,7 @@ #include "pacconf.h" #include "rpmvercmp.h" #include "md5.h" +#include "sha1.h" #include "list.h" #include "package.h" #include "util.h" @@ -1248,39 +1249,54 @@ syncpkg_t *sync; char str[PATH_MAX], pkgname[PATH_MAX]; char *md5sum1, *md5sum2; + char *sha1sum1, *sha1sum2; sync = (syncpkg_t*)i->data; snprintf(pkgname, PATH_MAX, "%s-%s%s", sync->pkg->name, sync->pkg->version, PKGEXT); md5sum1 = sync->pkg->md5sum; - if(md5sum1 == NULL || md5sum1[0] == '\0') { + sha1sum1 = sync->pkg->sha1sum; + if((md5sum1 == NULL || md5sum1[0] == '\0') && + (sha1sum1 == NULL || sha1sum1[0] == '\0')) { if(allgood) { printf("\n"); } - fprintf(stderr, "error: can't get md5 checksum for package %s\n", pkgname); + fprintf(stderr, "error: can't get md5 or sha1 checksum for package %s\n", pkgname); + vprint("error: md5 (1) %s\n", md5sum1); + vprint("error: sha1 (1) %s\n", sha1sum1); allgood = 0; continue; } snprintf(str, PATH_MAX, "%s/%s", ldir, pkgname); + md5sum2 = MDFile(str); - if(md5sum2 == NULL || md5sum2[0] == '\0') { + sha1sum2 = SHAFile(str); + + if((md5sum2 == NULL || md5sum2[0] == '\0') || + (sha1sum2 == NULL || sha1sum2[0] == '\0')) { if(allgood) { printf("\n"); } - fprintf(stderr, "error: can't get md5 checksum for archive %s\n", pkgname); + fprintf(stderr, "error: can't get md5 or sha1 checksum for archive %s\n", pkgname); + vprint("error: md5 (2) %s\n", md5sum2); + vprintf("error: sha1 (2) %s\n", sha1sum2); allgood = 0; continue; } - if(strcmp(md5sum1, md5sum2) != 0) { + if((strcmp(md5sum1, md5sum2) != 0) && + (strcmp(sha1sum1, sha1sum2) != 0)) { if(allgood) { printf("\n"); } - fprintf(stderr, "error: archive %s is corrupted\n", pkgname); + fprintf(stderr, "error: archive %s is corrupted (bad MD5 or SHA1 checksum)\n", pkgname); + vprint("error: sha(1) %s - sha(2) %s\n", sha1sum1, sha1sum2); + vprint("error: md5(1) %s - md5(2) %s\n", md5sum1, md5sum2); allgood = 0; } FREE(md5sum2); + FREE(sha1sum2); } if(allgood) { printf("done.\n"); @@ -1806,6 +1822,7 @@ int nb = 0; int notouch = 0; char *md5_orig = NULL; + char *sha1_orig = NULL; char pathname[PATH_MAX]; strncpy(pathname, archive_entry_pathname (entry), PATH_MAX); @@ -1853,7 +1870,8 @@ } else { /* op == PM_UPGRADE */ md5_orig = needbackup(pathname, oldpkg->backup); - if(md5_orig) { + sha1_orig = needbackup(pathname, oldpkg->backup); + if(md5_orig || sha1_orig) { nb = 1; } } @@ -1863,9 +1881,11 @@ if(nb) { char *temp; char *md5_local, *md5_pkg; + char *sha1_local, *sha1_pkg; md5_local = MDFile(expath); - /* extract the package's version to a temporary file and md5 it */ + sha1_local = SHAFile(expath); + /* extract the package's version to a temporary file and md5 or sha1 it */ temp = strdup("/tmp/pacman_XXXXXX"); mkstemp(temp); archive_entry_set_pathname (entry, temp); @@ -1875,7 +1895,8 @@ continue; } md5_pkg = MDFile(temp); - /* append the new md5 hash to it's respective entry in info->backup + sha1_pkg = SHAFile(temp); + /* append the new md5 / sha1 hash to it's respective entry in info->backup * (it will be the new orginal) */ for(lp = info->backup; lp; lp = lp->next) { @@ -1883,19 +1904,30 @@ if(!lp->data) continue; if(!strcmp((char*)lp->data, pathname)) { + /* KRIX */ /* 32 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */ - MALLOC(fn, strlen(lp->data)+34); - sprintf(fn, "%s\t%s", (char*)lp->data, md5_pkg); + if (info->sha1sum != NULL && info->sha1sum != '\0') { + MALLOC(fn, strlen(lp->data)+34); + sprintf(fn, "%s\t%s", (char*)lp->data, md5_pkg); + } else { + MALLOC(fn, strlen(lp->data)+43); + sprintf(fn, "%s\t%s", (char*)lp->data, sha1_pkg); + } FREE(lp->data); lp->data = fn; } } - vprint("checking md5 hashes for %s\n", expath); - vprint(" current: %s\n", md5_local); - vprint(" new: %s\n", md5_pkg); - if(md5_orig) { - vprint(" original: %s\n", md5_orig); + if (info->sha1sum != NULL && info->sha1sum != '\0') { + vprint("checking md5 hashes for %s\n", expath); + vprint(" current: %s\n", md5_local); + vprint(" new: %s\n", md5_pkg); + if(md5_orig) vprint(" original: %s\n", md5_orig); + } else { + vprint("checking sha1 hashes for %s\n", expath); + vprint(" current: %s\n", sha1_local); + vprint(" new: %s\n", sha1_pkg); + if(sha1_orig) vprint(" original: %s\n", sha1_orig); } if(!pmo_upgrade) { @@ -1903,7 +1935,7 @@ /* if a file already exists with a different md5 hash, * then we rename it to a .pacorig extension and continue */ - if(strcmp(md5_local, md5_pkg)) { + if(strcmp(md5_local, md5_pkg) || (strcmp(sha1_local, sha1_pkg))) { char newpath[PATH_MAX]; snprintf(newpath, PATH_MAX, "%s.pacorig", expath); if(rename(expath, newpath)) { @@ -1919,22 +1951,22 @@ logaction(stderr, "warning: %s saved as %s", expath, newpath); } } - } else if(md5_orig) { + } else if(md5_orig || sha1_orig) { /* PM_UPGRADE */ int installnew = 0; /* the fun part */ - if(!strcmp(md5_orig, md5_local)) { - if(!strcmp(md5_local, md5_pkg)) { + if(!strcmp(md5_orig, md5_local) || !strcmp(sha1_orig, sha1_local)) { + if(!strcmp(md5_local, md5_pkg) || !strcmp(sha1_local, sha1_pkg)) { vprint(" action: installing new file\n"); installnew = 1; } else { vprint(" action: installing new file\n"); installnew = 1; } - } else if(!strcmp(md5_orig, md5_pkg)) { + } else if(!strcmp(md5_orig, md5_pkg) || !strcmp(sha1_orig, sha1_pkg)) { vprint(" action: leaving existing file in place\n"); - } else if(!strcmp(md5_local, md5_pkg)) { + } else if(!strcmp(md5_local, md5_pkg) || !strcmp(sha1_local, sha1_pkg)) { vprint(" action: installing new file\n"); installnew = 1; } else { @@ -1962,6 +1994,9 @@ FREE(md5_local); FREE(md5_pkg); FREE(md5_orig); + FREE(sha1_local); + FREE(sha1_pkg); + FREE(sha1_orig); unlink(temp); FREE(temp); } else { @@ -1986,18 +2021,25 @@ logaction(stderr, "could not extract %s: %s", expath, strerror(errno)); errors++; } - /* calculate an md5 hash if this is in info->backup */ + /* calculate an md5 or sha1 hash if this is in info->backup */ for(lp = info->backup; lp; lp = lp->next) { - char *fn, *md5; + char *fn, *md5, *sha1; char path[PATH_MAX]; if(!lp->data) continue; if(!strcmp((char*)lp->data, pathname)) { snprintf(path, PATH_MAX, "%s%s", pmo_root, (char*)lp->data); - md5 = MDFile(path); /* 32 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */ + if (info->sha1sum != NULL && info->sha1sum != '\0') { + md5 = MDFile(path); MALLOC(fn, strlen(lp->data)+34); sprintf(fn, "%s\t%s", (char*)lp->data, md5); + /* 41 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */ + } else { + sha1 = SHAFile(path); + MALLOC(fn, strlen(lp->data)+43); + sprintf(fn, "%s\t%s", (char*)lp->data, sha1); + } free(lp->data); lp->data = fn; } @@ -2576,7 +2618,7 @@ for(lp = info->backup; lp; lp = lp->next) { struct stat buf; char path[PATH_MAX]; - char *md5sum; + char *md5sum, *sha1sum; char *str = strdup(lp->data); char *ptr = index(str, '\t'); if(ptr == NULL) { @@ -2588,11 +2630,12 @@ snprintf(path, PATH_MAX-1, "%s%s", pmo_root, str); if(!stat(path, &buf)) { md5sum = MDFile(path); - if(md5sum == NULL) { + sha1sum = SHAFile(path); + if(md5sum == NULL || sha1sum == NULL) { fprintf(stderr, "error calculating md5sum for %s\n", path); continue; } - if(strcmp(md5sum, ptr)) { + if(strcmp(md5sum, ptr) || strcmp(sha1sum, ptr)) { printf("MODIFIED\t%s\n", path); } else { printf("NOT MODIFIED\t%s\n", path); @@ -3357,13 +3400,13 @@ } /* Look for a filename in a pkginfo_t.backup list. If we find it, - * then we return the md5 hash (parsed from the same line) + * then we return the md5 or sha1 hash (parsed from the same line) */ char* needbackup(char* file, PMList *backup) { PMList *lp; - /* run through the backup list and parse out the md5 hash for our file */ + /* run through the backup list and parse out the md5 or sha1 hash for our file */ for(lp = backup; lp; lp = lp->next) { char* str = strdup(lp->data); char* ptr; @@ -3376,7 +3419,7 @@ } *ptr = '\0'; ptr++; - /* now str points to the filename and ptr points to the md5 hash */ + /* now str points to the filename and ptr points to the md5 or sha1 hash */ if(!strcmp(file, str)) { char *md5 = strdup(ptr); FREE(str); diff -Naur pacman-2.9.6.orig/src/sha1.c pacman-2.9.6/src/sha1.c --- pacman-2.9.6.orig/src/sha1.c 1970-01-01 01:00:00.000000000 +0100 +++ pacman-2.9.6/src/sha1.c 2005-08-15 16:02:24.000000000 +0200 @@ -0,0 +1,482 @@ +/* sha.c - Functions to compute SHA1 message digest of files or + memory blocks according to the NIST specification FIPS-180-1. + + Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. + + 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 the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* Written by Scott G. Miller + Credits: + Robert Klep -- Expansion function fix +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "sha1.h" + +#include + +#include +#include +#include + +/* + Not-swap is a macro that does an endian swap on architectures that are + big-endian, as SHA needs some data in a little-endian format +*/ + +#ifdef WORDS_BIGENDIAN +# define NOTSWAP(n) (n) +# define SWAP(n) \ + (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) +#else +# define NOTSWAP(n) \ + (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) +# define SWAP(n) (n) +#endif + +#define BLOCKSIZE 4096 +/* Ensure that BLOCKSIZE is a multiple of 64. */ +#if BLOCKSIZE % 64 != 0 +/* FIXME-someday (soon?): use #error instead of this kludge. */ +"invalid BLOCKSIZE" +#endif + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (RFC 1321, 3.1: Step 1) */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* + Takes a pointer to a 160 bit block of data (five 32 bit ints) and + intializes it to the start constants of the SHA1 algorithm. This + must be called before using hash in the call to sha_hash +*/ +void +sha_init_ctx (struct sha_ctx *ctx) +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; + ctx->E = 0xc3d2e1f0; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + +/* Put result from CTX in first 20 bytes following RESBUF. The result + must be in little endian byte order. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +sha_read_ctx (const struct sha_ctx *ctx, void *resbuf) +{ + ((sha_uint32 *) resbuf)[0] = NOTSWAP (ctx->A); + ((sha_uint32 *) resbuf)[1] = NOTSWAP (ctx->B); + ((sha_uint32 *) resbuf)[2] = NOTSWAP (ctx->C); + ((sha_uint32 *) resbuf)[3] = NOTSWAP (ctx->D); + ((sha_uint32 *) resbuf)[4] = NOTSWAP (ctx->E); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +sha_finish_ctx (struct sha_ctx *ctx, void *resbuf) +{ + /* Take yet unprocessed bytes into account. */ + sha_uint32 bytes = ctx->buflen; + size_t pad; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; + memcpy (&ctx->buffer[bytes], fillbuf, pad); + + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + *(sha_uint32 *) &ctx->buffer[bytes + pad + 4] = NOTSWAP (ctx->total[0] << 3); + *(sha_uint32 *) &ctx->buffer[bytes + pad] = NOTSWAP ((ctx->total[1] << 3) | + (ctx->total[0] >> 29)); + + /* Process last bytes. */ + sha_process_block (ctx->buffer, bytes + pad + 8, ctx); + + return sha_read_ctx (ctx, resbuf); +} + +/* Compute SHA1 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +int +sha_stream (FILE *stream, void *resblock) +{ + struct sha_ctx ctx; + char buffer[BLOCKSIZE + 72]; + size_t sum; + + /* Initialize the computation context. */ + sha_init_ctx (&ctx); + + /* Iterate over full file contents. */ + while (1) + { + /* We read the file in blocks of BLOCKSIZE bytes. One call of the + computation function processes the whole buffer so that with the + next round of the loop another block can be read. */ + size_t n; + sum = 0; + + /* Read block. Take care for partial reads. */ + while (1) + { + n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); + + sum += n; + + if (sum == BLOCKSIZE) + break; + + if (n == 0) + { + /* Check for the error flag IFF N == 0, so that we don't + exit the loop after a partial read due to e.g., EAGAIN + or EWOULDBLOCK. */ + if (ferror (stream)) + return 1; + goto process_partial_block; + } + + /* We've read at least one byte, so ignore errors. But always + check for EOF, since feof may be true even though N > 0. + Otherwise, we could end up calling fread after EOF. */ + if (feof (stream)) + goto process_partial_block; + } + + /* Process buffer with BLOCKSIZE bytes. Note that + BLOCKSIZE % 64 == 0 + */ + sha_process_block (buffer, BLOCKSIZE, &ctx); + } + + process_partial_block:; + + /* Process any remaining bytes. */ + if (sum > 0) + sha_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + sha_finish_ctx (&ctx, resblock); + return 0; +} + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +void * +sha_buffer (const char *buffer, size_t len, void *resblock) +{ + struct sha_ctx ctx; + + /* Initialize the computation context. */ + sha_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + sha_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return sha_finish_ctx (&ctx, resblock); +} + +void +sha_process_bytes (const void *buffer, size_t len, struct sha_ctx *ctx) +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; + + memcpy (&ctx->buffer[left_over], buffer, add); + ctx->buflen += add; + + if (ctx->buflen > 64) + { + sha_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + + ctx->buflen &= 63; + /* The regions in the following copy operation cannot overlap. */ + memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], + ctx->buflen); + } + + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 64) + { +#if !_STRING_ARCH_unaligned +/* To check alignment gcc has an appropriate operator. Other + compilers don't. */ +# if __GNUC__ >= 2 +# define UNALIGNED_P(p) (((sha_uintptr) p) % __alignof__ (sha_uint32) != 0) +# else +# define UNALIGNED_P(p) (((sha_uintptr) p) % sizeof (sha_uint32) != 0) +# endif + if (UNALIGNED_P (buffer)) + while (len > 64) + { + sha_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif + { + sha_process_block (buffer, len & ~63, ctx); + buffer = (const char *) buffer + (len & ~63); + len &= 63; + } + } + + /* Move remaining bytes in internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&ctx->buffer[left_over], buffer, len); + left_over += len; + if (left_over >= 64) + { + sha_process_block (ctx->buffer, 64, ctx); + left_over -= 64; + memcpy (ctx->buffer, &ctx->buffer[64], left_over); + } + ctx->buflen = left_over; + } +} + +/* --- Code below is the primary difference between md5.c and sha.c --- */ + +/* SHA1 round constants */ +#define K1 0x5a827999L +#define K2 0x6ed9eba1L +#define K3 0x8f1bbcdcL +#define K4 0xca62c1d6L + +/* Round functions. Note that F2 is the same as F4. */ +#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) ) +#define F2(B,C,D) (B ^ C ^ D) +#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) ) +#define F4(B,C,D) (B ^ C ^ D) + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. + Most of this code comes from GnuPG's cipher/sha1.c. */ + +void +sha_process_block (const void *buffer, size_t len, struct sha_ctx *ctx) +{ + const sha_uint32 *words = buffer; + size_t nwords = len / sizeof (sha_uint32); + const sha_uint32 *endp = words + nwords; + sha_uint32 x[16]; + sha_uint32 a = ctx->A; + sha_uint32 b = ctx->B; + sha_uint32 c = ctx->C; + sha_uint32 d = ctx->D; + sha_uint32 e = ctx->E; + + /* First increment the byte count. RFC 1321 specifies the possible + length of the file up to 2^64 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += len; + if (ctx->total[0] < len) + ++ctx->total[1]; + +#define M(I) ( tm = x[I&0x0f] ^ x[(I-14)&0x0f] \ + ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \ + , (x[I&0x0f] = rol(tm, 1)) ) + +#define R(A,B,C,D,E,F,K,M) do { E += rol( A, 5 ) \ + + F( B, C, D ) \ + + K \ + + M; \ + B = rol( B, 30 ); \ + } while(0) + + while (words < endp) + { + sha_uint32 tm; + int t; + /* FIXME: see sha1.c for a better implementation. */ + for (t = 0; t < 16; t++) + { + x[t] = NOTSWAP (*words); + words++; + } + + R( a, b, c, d, e, F1, K1, x[ 0] ); + R( e, a, b, c, d, F1, K1, x[ 1] ); + R( d, e, a, b, c, F1, K1, x[ 2] ); + R( c, d, e, a, b, F1, K1, x[ 3] ); + R( b, c, d, e, a, F1, K1, x[ 4] ); + R( a, b, c, d, e, F1, K1, x[ 5] ); + R( e, a, b, c, d, F1, K1, x[ 6] ); + R( d, e, a, b, c, F1, K1, x[ 7] ); + R( c, d, e, a, b, F1, K1, x[ 8] ); + R( b, c, d, e, a, F1, K1, x[ 9] ); + R( a, b, c, d, e, F1, K1, x[10] ); + R( e, a, b, c, d, F1, K1, x[11] ); + R( d, e, a, b, c, F1, K1, x[12] ); + R( c, d, e, a, b, F1, K1, x[13] ); + R( b, c, d, e, a, F1, K1, x[14] ); + R( a, b, c, d, e, F1, K1, x[15] ); + R( e, a, b, c, d, F1, K1, M(16) ); + R( d, e, a, b, c, F1, K1, M(17) ); + R( c, d, e, a, b, F1, K1, M(18) ); + R( b, c, d, e, a, F1, K1, M(19) ); + R( a, b, c, d, e, F2, K2, M(20) ); + R( e, a, b, c, d, F2, K2, M(21) ); + R( d, e, a, b, c, F2, K2, M(22) ); + R( c, d, e, a, b, F2, K2, M(23) ); + R( b, c, d, e, a, F2, K2, M(24) ); + R( a, b, c, d, e, F2, K2, M(25) ); + R( e, a, b, c, d, F2, K2, M(26) ); + R( d, e, a, b, c, F2, K2, M(27) ); + R( c, d, e, a, b, F2, K2, M(28) ); + R( b, c, d, e, a, F2, K2, M(29) ); + R( a, b, c, d, e, F2, K2, M(30) ); + R( e, a, b, c, d, F2, K2, M(31) ); + R( d, e, a, b, c, F2, K2, M(32) ); + R( c, d, e, a, b, F2, K2, M(33) ); + R( b, c, d, e, a, F2, K2, M(34) ); + R( a, b, c, d, e, F2, K2, M(35) ); + R( e, a, b, c, d, F2, K2, M(36) ); + R( d, e, a, b, c, F2, K2, M(37) ); + R( c, d, e, a, b, F2, K2, M(38) ); + R( b, c, d, e, a, F2, K2, M(39) ); + R( a, b, c, d, e, F3, K3, M(40) ); + R( e, a, b, c, d, F3, K3, M(41) ); + R( d, e, a, b, c, F3, K3, M(42) ); + R( c, d, e, a, b, F3, K3, M(43) ); + R( b, c, d, e, a, F3, K3, M(44) ); + R( a, b, c, d, e, F3, K3, M(45) ); + R( e, a, b, c, d, F3, K3, M(46) ); + R( d, e, a, b, c, F3, K3, M(47) ); + R( c, d, e, a, b, F3, K3, M(48) ); + R( b, c, d, e, a, F3, K3, M(49) ); + R( a, b, c, d, e, F3, K3, M(50) ); + R( e, a, b, c, d, F3, K3, M(51) ); + R( d, e, a, b, c, F3, K3, M(52) ); + R( c, d, e, a, b, F3, K3, M(53) ); + R( b, c, d, e, a, F3, K3, M(54) ); + R( a, b, c, d, e, F3, K3, M(55) ); + R( e, a, b, c, d, F3, K3, M(56) ); + R( d, e, a, b, c, F3, K3, M(57) ); + R( c, d, e, a, b, F3, K3, M(58) ); + R( b, c, d, e, a, F3, K3, M(59) ); + R( a, b, c, d, e, F4, K4, M(60) ); + R( e, a, b, c, d, F4, K4, M(61) ); + R( d, e, a, b, c, F4, K4, M(62) ); + R( c, d, e, a, b, F4, K4, M(63) ); + R( b, c, d, e, a, F4, K4, M(64) ); + R( a, b, c, d, e, F4, K4, M(65) ); + R( e, a, b, c, d, F4, K4, M(66) ); + R( d, e, a, b, c, F4, K4, M(67) ); + R( c, d, e, a, b, F4, K4, M(68) ); + R( b, c, d, e, a, F4, K4, M(69) ); + R( a, b, c, d, e, F4, K4, M(70) ); + R( e, a, b, c, d, F4, K4, M(71) ); + R( d, e, a, b, c, F4, K4, M(72) ); + R( c, d, e, a, b, F4, K4, M(73) ); + R( b, c, d, e, a, F4, K4, M(74) ); + R( a, b, c, d, e, F4, K4, M(75) ); + R( e, a, b, c, d, F4, K4, M(76) ); + R( d, e, a, b, c, F4, K4, M(77) ); + R( c, d, e, a, b, F4, K4, M(78) ); + R( b, c, d, e, a, F4, K4, M(79) ); + + a = ctx->A += a; + b = ctx->B += b; + c = ctx->C += c; + d = ctx->D += d; + e = ctx->E += e; + } +} + +/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All +rights reserved. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + */ + + +char* SHAFile(char *filename) { + FILE *file; + struct sha_ctx context; + int len, i; + unsigned char buffer[1024], digest[20]; + char *ret; + + if((file = fopen(filename, "rb")) == NULL) { + fprintf(stderr, "%s can't be opened\n", filename); + } else { + sha_init_ctx(&context); + while((len = fread(buffer, 1, 1024, file))) { + sha_process_bytes(buffer, len, &context); + } + sha_finish_ctx(&context, digest); + fclose(file); +#ifdef DEBUG + SHAPrint(digest); +#endif + ret = (char*)malloc(41); + ret[0] = '\0'; + for(i = 0; i < 20; i++) { + sprintf(ret, "%s%02x", ret, digest[i]); + } + return(ret); + } + + return(NULL); +} + +void SHAPrint(unsigned char digest[20]) { + unsigned int i; + for (i = 0; i < 20; i++) + printf ("\n%02x", digest[i]); +} diff -Naur pacman-2.9.6.orig/src/sha1.h pacman-2.9.6/src/sha1.h --- pacman-2.9.6.orig/src/sha1.h 1970-01-01 01:00:00.000000000 +0100 +++ pacman-2.9.6/src/sha1.h 2005-08-15 16:01:58.000000000 +0200 @@ -0,0 +1,108 @@ +/* Declarations of functions and data types used for SHA1 sum + library functions. + Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. + + 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 the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include +#include + +#define rol(x,n) ( ((x) << (n)) | ((x) >> (32 -(n))) ) +/* The code below is from md5.h (from coreutils), little modifications */ +#define UINT_MAX_32_BITS 4294967295U + +#if UINT_MAX == UINT_MAX_32_BITS + typedef unsigned int sha_uint32; +#else +#if USHRT_MAX == UINT_MAX_32_BITS + typedef unsigned short sha_uint32; +#else +#if ULONG_MAX == UINT_MAX_32_BITS + typedef unsigned long sha_uint32; +#else + /* The following line is intended to evoke an error. Using #error is not portable enough. */ +#error "Cannot determine unsigned 32-bit data type" +#endif +#endif +#endif +/* We have to make a guess about the integer type equivalent in size + to pointers which should always be correct. */ +typedef unsigned long int sha_uintptr; + +/* Structure to save state of computation between the single steps. */ +struct sha_ctx +{ + sha_uint32 A; + sha_uint32 B; + sha_uint32 C; + sha_uint32 D; + sha_uint32 E; + + sha_uint32 total[2]; + sha_uint32 buflen; + char buffer[128]; +}; + + +/* Initialize structure containing state of computation. */ +extern void sha_init_ctx (struct sha_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void sha_process_block (const void *buffer, size_t len, + struct sha_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void sha_process_bytes (const void *buffer, size_t len, + struct sha_ctx *ctx); + +/* Process the remaining bytes in the buffer and put result from CTX + in first 20 bytes following RESBUF. The result is always in little + endian byte order, so that a byte-wise output yields to the wanted + ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF be correctly + aligned for a 32 bits value. */ +extern void *sha_finish_ctx (struct sha_ctx *ctx, void *resbuf); + + +/* Put result from CTX in first 20 bytes following RESBUF. The result is + always in little endian byte order, so that a byte-wise output yields + to the wanted ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *sha_read_ctx (const struct sha_ctx *ctx, void *resbuf); + + +/* Compute SHA1 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 20 bytes + beginning at RESBLOCK. */ +extern int sha_stream (FILE *stream, void *resblock); + +/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +extern void *sha_buffer (const char *buffer, size_t len, void *resblock); + +/* Needed for pacman */ +char *SHAFile (char *); +void SHAPrint(unsigned char [16]);