added file and segment lengths to checksum.c
authorAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 21 Jul 2009 20:23:51 +0000 (22:23 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 21 Jul 2009 20:23:51 +0000 (22:23 +0200)
src/checksum/checksum_builder.c
src/libstrongswan/integrity_checker.c
src/libstrongswan/integrity_checker.h

index d2c042d..71cca1d 100644 (file)
@@ -44,12 +44,16 @@ int main(int argc, char* argv[])
        printf("#include <library.h>\n");
        printf("\n");
        printf("integrity_checksum_t checksums[] = {\n");
+       fprintf(stderr, "integrity test data:\n");
+       fprintf(stderr, "module name,       file size / checksum   segment size / checksum\n");
        for (i = 1; i < argc; i++)
        {
                char *name, *path, *sname = NULL;
                void *handle, *symbol;
                u_int32_t fsum, ssum;
-               
+               size_t fsize = 0;
+               size_t ssize = 0;
+
                path = argv[i];
                
                if ((name = strstr(path, "libstrongswan-")))
@@ -79,7 +83,7 @@ int main(int argc, char* argv[])
                        continue;
                }
                
-               fsum = integrity->build_file(integrity, path);
+               fsum = integrity->build_file(integrity, path, &fsize);
                ssum = 0;
                if (sname)
                {
@@ -89,7 +93,7 @@ int main(int argc, char* argv[])
                                symbol = dlsym(handle, sname);
                                if (symbol)
                                {
-                                       ssum = integrity->build_segment(integrity, symbol);
+                                       ssum = integrity->build_segment(integrity, symbol, &ssize);
                                }
                                else
                                {
@@ -102,7 +106,10 @@ int main(int argc, char* argv[])
                                fprintf(stderr, "dlopen failed: %s\n", dlerror());
                        }
                }
-               printf("\t{\"%-20s0x%08x, 0x%08x},\n", name, fsum, ssum);
+               printf("\t{\"%-20s%7u, 0x%08x, %6u, 0x%08x},\n",
+                          name, fsize, fsum, ssize, ssum);
+               fprintf(stderr, "\"%-20s%7u / 0x%08x       %6u / 0x%08x\n", 
+                               name, fsize, fsum, ssize, ssum);
                free(name);
        }
        printf("};\n");
index eb0bc14..32a296d 100644 (file)
@@ -60,7 +60,8 @@ struct private_integrity_checker_t {
 /**
  * Implementation of integrity_checker_t.build_file
  */
-static u_int32_t build_file(private_integrity_checker_t *this, char *file)
+static u_int32_t build_file(private_integrity_checker_t *this, char *file,
+                                                       size_t *len)
 {
        u_int32_t checksum;
        chunk_t contents;
@@ -71,13 +72,13 @@ static u_int32_t build_file(private_integrity_checker_t *this, char *file)
        fd = open(file, O_RDONLY);
        if (fd == -1)
        {
-               DBG1("opening '%s' failed: %s", file, strerror(errno));
+               DBG1("  opening '%s' failed: %s", file, strerror(errno));
                return 0;
        }
        
        if (fstat(fd, &sb) == -1)
        {
-               DBG1("getting file size of '%s' failed: %s", file, strerror(errno));
+               DBG1("  getting file size of '%s' failed: %s", file, strerror(errno));
                close(fd);
                return 0;
        }
@@ -85,11 +86,12 @@ static u_int32_t build_file(private_integrity_checker_t *this, char *file)
        addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
        if (addr == MAP_FAILED)
        {
-               DBG1("mapping '%s' failed: %s", file, strerror(errno));
+               DBG1("  mapping '%s' failed: %s", file, strerror(errno));
                close(fd);
                return 0;
        }
-       
+
+       *len = sb.st_size;      
        contents = chunk_create(addr, sb.st_size);
        checksum = chunk_hash(contents);
        
@@ -136,24 +138,26 @@ static int callback(struct dl_phdr_info *dlpi, size_t size, Dl_info *dli)
 /**
  * Implementation of integrity_checker_t.build_segment
  */
-static u_int32_t build_segment(private_integrity_checker_t *this, void *sym)
+static u_int32_t build_segment(private_integrity_checker_t *this, void *sym,
+                                                          size_t *len)
 {
        chunk_t segment;
        Dl_info dli;
        
        if (dladdr(sym, &dli) == 0)
        {
-               DBG1("unable to locate symbol: %s", dlerror());
+               DBG1("  unable to locate symbol: %s", dlerror());
                return 0;
        }
        /* we reuse the Dl_info struct as in/out parameter */
        if (!dl_iterate_phdr((void*)callback, &dli))
        {
-               DBG1("executable section not found");
+               DBG1("  executable section not found");
                return 0;
        }
        
        segment = chunk_create(dli.dli_fbase, dli.dli_saddr - dli.dli_fbase);
+       *len = segment.len;
        return chunk_hash(segment);
 }
 
@@ -183,6 +187,7 @@ static bool check_file(private_integrity_checker_t *this,
 {
        integrity_checksum_t *cs;
        u_int32_t sum;
+       size_t len = 0;
        
        cs = find_checksum(this, name);
        if (!cs)
@@ -190,8 +195,18 @@ static bool check_file(private_integrity_checker_t *this,
                DBG1("  '%s' file checksum not found", name);
                return FALSE;
        }
-       sum = build_file(this, file);
-       if (!sum || cs->file != sum)
+       sum = build_file(this, file, &len);
+       if (!sum)
+       {
+               return FALSE;
+       }
+       if (cs->file_len != len)
+       {
+               DBG1("  invalid '%s' file size: %u bytes, expected %u bytes",
+                        name, len, cs->file_len);
+               return FALSE;
+       }
+       if (cs->file != sum)
        {
                DBG1("  invalid '%s' file checksum: %08x, expected %08x",
                         name, sum, cs->file);
@@ -209,6 +224,7 @@ static bool check_segment(private_integrity_checker_t *this,
 {
        integrity_checksum_t *cs;
        u_int32_t sum;
+       size_t len = 0;
        
        cs = find_checksum(this, name);
        if (!cs)
@@ -216,8 +232,18 @@ static bool check_segment(private_integrity_checker_t *this,
                DBG1("  '%s' segment checksum not found", name);
                return FALSE;
        }
-       sum = build_segment(this, sym);
-       if (!sum || cs->segment != sum)
+       sum = build_segment(this, sym, &len);
+       if (!sum)
+       {
+               return FALSE;
+       }
+       if (cs->segment_len != len)
+       {
+               DBG1("  invalid '%s' segment size: %u bytes, expected %u bytes",
+                        name, len, cs->segment_len);
+               return FALSE;
+       }
+       if (cs->segment != sum)
        {
                DBG1("  invalid '%s' segment checksum: %08x, expected %08x",
                         name, sum, cs->segment);
@@ -270,9 +296,9 @@ integrity_checker_t *integrity_checker_create(char *checksum_library)
        private_integrity_checker_t *this = malloc_thing(private_integrity_checker_t);
        
        this->public.check_file = (bool(*)(integrity_checker_t*, char *name, char *file))check_file;
-       this->public.build_file = (u_int32_t(*)(integrity_checker_t*, char *file))build_file;
+       this->public.build_file = (u_int32_t(*)(integrity_checker_t*, char *file, size_t *len))build_file;
        this->public.check_segment = (bool(*)(integrity_checker_t*, char *name, void *sym))check_segment;
-       this->public.build_segment = (u_int32_t(*)(integrity_checker_t*, void *sym))build_segment;
+       this->public.build_segment = (u_int32_t(*)(integrity_checker_t*, void *sym, size_t *len))build_segment;
        this->public.check = (bool(*)(integrity_checker_t*, char *name, void *sym))check;
        this->public.destroy = (void(*)(integrity_checker_t*))destroy;
        
index d10de5b..d078dd6 100644 (file)
@@ -33,8 +33,12 @@ typedef struct integrity_checksum_t integrity_checksum_t;
 struct integrity_checksum_t {
        /* name of the checksum */
        char *name;
+       /* size in bytes of the file on disk */
+       size_t file_len; 
        /* checksum of the file on disk */
        u_int32_t file;
+       /* size in bytes of executable segment in memory */
+       size_t segment_len; 
        /* checksum of the executable segment in memory */
        u_int32_t segment;
 };
@@ -60,9 +64,10 @@ struct integrity_checker_t {
         * Build the integrity checksum of a file on disk.
         *
         * @param file          path to file
+        * @param len           return length in bytes of file
         * @return                      checksum, 0 on error
         */
-       u_int32_t (*build_file)(integrity_checker_t *this, char *file);
+       u_int32_t (*build_file)(integrity_checker_t *this, char *file, size_t *len);
        
        /**
         * Check the integrity of the code segment in memory.
@@ -72,14 +77,14 @@ struct integrity_checker_t {
         * @return                      TRUE if integrity tested successfully
         */
        bool (*check_segment)(integrity_checker_t *this, char *name, void *sym);
-       
        /**
         * Build the integrity checksum of a code segment in memory.
         *
         * @param sym           a symbol in the segment to check
+        * @param len           return length in bytes of code segment in memory
         * @return                      checksum, 0 on error
         */
-       u_int32_t (*build_segment)(integrity_checker_t *this, void *sym);
+       u_int32_t (*build_segment)(integrity_checker_t *this, void *sym, size_t *len);
        
        /**
         * Check both, on disk file integrity and loaded segment.