Moved integrity_checker_t to utils folder
authorTobias Brunner <tobias@strongswan.org>
Tue, 16 Oct 2012 13:39:26 +0000 (15:39 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 24 Oct 2012 14:00:50 +0000 (16:00 +0200)
src/libstrongswan/Makefile.am
src/libstrongswan/integrity_checker.c [deleted file]
src/libstrongswan/integrity_checker.h [deleted file]
src/libstrongswan/library.h
src/libstrongswan/plugins/plugin_loader.c
src/libstrongswan/utils/integrity_checker.c [new file with mode: 0644]
src/libstrongswan/utils/integrity_checker.h [new file with mode: 0644]

index 2fa9dab..3e549af 100644 (file)
@@ -70,7 +70,7 @@ threading/mutex.h threading/condvar.h threading/spinlock.h threading/semaphore.h
 threading/rwlock.h threading/rwlock_condvar.h threading/lock_profiler.h \
 utils.h utils/identification.h utils/lexparser.h \
 utils/optionsfrom.h utils/capabilities.h utils/backtrace.h \
-utils/leak_detective.h integrity_checker.h
+utils/leak_detective.h utils/integrity_checker.h
 endif
 
 library.lo :   $(top_builddir)/config.status
@@ -95,7 +95,7 @@ endif
 
 if USE_INTEGRITY_TEST
   AM_CFLAGS += -DINTEGRITY_TEST
-  libstrongswan_la_SOURCES += integrity_checker.c
+  libstrongswan_la_SOURCES += utils/integrity_checker.c
 endif
 
 if USE_VSTR
diff --git a/src/libstrongswan/integrity_checker.c b/src/libstrongswan/integrity_checker.c
deleted file mode 100644 (file)
index e962aba..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#define _GNU_SOURCE
-
-#include "integrity_checker.h"
-
-#include <dlfcn.h>
-#include <link.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "debug.h"
-#include "library.h"
-
-typedef struct private_integrity_checker_t private_integrity_checker_t;
-
-/**
- * Private data of an integrity_checker_t object.
- */
-struct private_integrity_checker_t {
-
-       /**
-        * Public integrity_checker_t interface.
-        */
-       integrity_checker_t public;
-
-       /**
-        * dlopen handle to checksum library
-        */
-       void *handle;
-
-       /**
-        * checksum array
-        */
-       integrity_checksum_t *checksums;
-
-       /**
-        * number of checksums in array
-        */
-       int checksum_count;
-};
-
-METHOD(integrity_checker_t, build_file, u_int32_t,
-       private_integrity_checker_t *this, char *file, size_t *len)
-{
-       u_int32_t checksum;
-       chunk_t contents;
-       struct stat sb;
-       void *addr;
-       int fd;
-
-       fd = open(file, O_RDONLY);
-       if (fd == -1)
-       {
-               DBG1(DBG_LIB, "  opening '%s' failed: %s", file, strerror(errno));
-               return 0;
-       }
-
-       if (fstat(fd, &sb) == -1)
-       {
-               DBG1(DBG_LIB, "  getting file size of '%s' failed: %s", file,
-                        strerror(errno));
-               close(fd);
-               return 0;
-       }
-
-       addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-       if (addr == MAP_FAILED)
-       {
-               DBG1(DBG_LIB, "  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);
-
-       munmap(addr, sb.st_size);
-       close(fd);
-
-       return checksum;
-}
-
-/**
- * dl_iterate_phdr callback function
- */
-static int callback(struct dl_phdr_info *dlpi, size_t size, Dl_info *dli)
-{
-       /* We are looking for the dlpi_addr matching the address of our dladdr().
-        * dl_iterate_phdr() returns such an address for other (unknown) objects
-        * in very rare cases (e.g. in a chrooted gentoo, but only if
-        * the checksum_builder is invoked by 'make'). As a workaround, we filter
-        * objects by dlpi_name; valid objects have a library name.
-        */
-       if (dli->dli_fbase == (void*)dlpi->dlpi_addr &&
-               dlpi->dlpi_name && *dlpi->dlpi_name)
-       {
-               int i;
-
-               for (i = 0; i < dlpi->dlpi_phnum; i++)
-               {
-                       const ElfW(Phdr) *sgmt = &dlpi->dlpi_phdr[i];
-
-                       /* we are interested in the executable LOAD segment */
-                       if (sgmt->p_type == PT_LOAD && (sgmt->p_flags & PF_X))
-                       {
-                               /* safe begin of segment in dli_fbase */
-                               dli->dli_fbase = (void*)sgmt->p_vaddr + dlpi->dlpi_addr;
-                               /* safe end of segment in dli_saddr */
-                               dli->dli_saddr = dli->dli_fbase + sgmt->p_memsz;
-                               return 1;
-                       }
-               }
-       }
-       return 0;
-}
-
-METHOD(integrity_checker_t, build_segment, u_int32_t,
-       private_integrity_checker_t *this, void *sym, size_t *len)
-{
-       chunk_t segment;
-       Dl_info dli;
-
-       if (dladdr(sym, &dli) == 0)
-       {
-               DBG1(DBG_LIB, "  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(DBG_LIB, "  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);
-}
-
-/**
- * Find a checksum by its name
- */
-static integrity_checksum_t *find_checksum(private_integrity_checker_t *this,
-                                                                                  char *name)
-{
-       int i;
-
-       for (i = 0; i < this->checksum_count; i++)
-       {
-               if (streq(this->checksums[i].name, name))
-               {
-                       return &this->checksums[i];
-               }
-       }
-       return NULL;
-}
-
-METHOD(integrity_checker_t, check_file, bool,
-       private_integrity_checker_t *this, char *name, char *file)
-{
-       integrity_checksum_t *cs;
-       u_int32_t sum;
-       size_t len = 0;
-
-       cs = find_checksum(this, name);
-       if (!cs)
-       {
-               DBG1(DBG_LIB, "  '%s' file checksum not found", name);
-               return FALSE;
-       }
-       sum = build_file(this, file, &len);
-       if (!sum)
-       {
-               return FALSE;
-       }
-       if (cs->file_len != len)
-       {
-               DBG1(DBG_LIB, "  invalid '%s' file size: %u bytes, expected %u bytes",
-                        name, len, cs->file_len);
-               return FALSE;
-       }
-       if (cs->file != sum)
-       {
-               DBG1(DBG_LIB, "  invalid '%s' file checksum: %08x, expected %08x",
-                        name, sum, cs->file);
-               return FALSE;
-       }
-       DBG2(DBG_LIB, "  valid '%s' file checksum: %08x", name, sum);
-       return TRUE;
-}
-
-METHOD(integrity_checker_t, check_segment, bool,
-       private_integrity_checker_t *this, char *name, void *sym)
-{
-       integrity_checksum_t *cs;
-       u_int32_t sum;
-       size_t len = 0;
-
-       cs = find_checksum(this, name);
-       if (!cs)
-       {
-               DBG1(DBG_LIB, "  '%s' segment checksum not found", name);
-               return FALSE;
-       }
-       sum = build_segment(this, sym, &len);
-       if (!sum)
-       {
-               return FALSE;
-       }
-       if (cs->segment_len != len)
-       {
-               DBG1(DBG_LIB, "  invalid '%s' segment size: %u bytes,"
-                        " expected %u bytes", name, len, cs->segment_len);
-               return FALSE;
-       }
-       if (cs->segment != sum)
-       {
-               DBG1(DBG_LIB, "  invalid '%s' segment checksum: %08x, expected %08x",
-                        name, sum, cs->segment);
-               return FALSE;
-       }
-       DBG2(DBG_LIB, "  valid '%s' segment checksum: %08x", name, sum);
-       return TRUE;
-}
-
-METHOD(integrity_checker_t, check, bool,
-       private_integrity_checker_t *this, char *name, void *sym)
-{
-       Dl_info dli;
-
-       if (dladdr(sym, &dli) == 0)
-       {
-               DBG1(DBG_LIB, "unable to locate symbol: %s", dlerror());
-               return FALSE;
-       }
-       if (!check_file(this, name, (char*)dli.dli_fname))
-       {
-               return FALSE;
-       }
-       if (!check_segment(this, name, sym))
-       {
-               return FALSE;
-       }
-       return TRUE;
-}
-
-METHOD(integrity_checker_t, destroy, void,
-       private_integrity_checker_t *this)
-{
-       if (this->handle)
-       {
-               dlclose(this->handle);
-       }
-       free(this);
-}
-
-/**
- * See header
- */
-integrity_checker_t *integrity_checker_create(char *checksum_library)
-{
-       private_integrity_checker_t *this;
-
-       INIT(this,
-               .public = {
-                       .check_file = _check_file,
-                       .build_file = _build_file,
-                       .check_segment = _check_segment,
-                       .build_segment = _build_segment,
-                       .check = _check,
-                       .destroy = _destroy,
-               },
-       );
-
-       if (checksum_library)
-       {
-               this->handle = dlopen(checksum_library, RTLD_LAZY);
-               if (this->handle)
-               {
-                       int *checksum_count;
-
-                       this->checksums = dlsym(this->handle, "checksums");
-                       checksum_count = dlsym(this->handle, "checksum_count");
-                       if (this->checksums && checksum_count)
-                       {
-                               this->checksum_count = *checksum_count;
-                       }
-                       else
-                       {
-                               DBG1(DBG_LIB, "checksum library '%s' invalid",
-                                        checksum_library);
-                       }
-               }
-               else
-               {
-                       DBG1(DBG_LIB, "loading checksum library '%s' failed",
-                                checksum_library);
-               }
-       }
-       return &this->public;
-}
-
diff --git a/src/libstrongswan/integrity_checker.h b/src/libstrongswan/integrity_checker.h
deleted file mode 100644 (file)
index 891cccc..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-/**
- * @defgroup integrity_checker integrity_checker
- * @{ @ingroup libstrongswan
- */
-
-#ifndef INTEGRITY_CHECKER_H_
-#define INTEGRITY_CHECKER_H_
-
-#include "utils.h"
-
-typedef struct integrity_checker_t integrity_checker_t;
-typedef struct integrity_checksum_t integrity_checksum_t;
-
-/**
- * Struct to hold a precalculated checksum, implemented in the checksum library.
- */
-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;
-};
-
-/**
- * Code integrity checker to detect non-malicious file manipulation.
- *
- * The integrity checker reads the checksums from a separate library
- * libchecksum.so to compare the checksums.
- */
-struct integrity_checker_t {
-
-       /**
-        * Check the integrity of a file on disk.
-        *
-        * @param name          name to lookup checksum
-        * @param file          path to file
-        * @return                      TRUE if integrity tested successfully
-        */
-       bool (*check_file)(integrity_checker_t *this, char *name, char *file);
-
-       /**
-        * 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, size_t *len);
-
-       /**
-        * Check the integrity of the code segment in memory.
-        *
-        * @param name          name to lookup checksum
-        * @param sym           a symbol in the segment to check
-        * @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, size_t *len);
-
-       /**
-        * Check both, on disk file integrity and loaded segment.
-        *
-        * @param name          name to lookup checksum
-        * @param sym           a symbol to look up library and segment
-        * @return                      TRUE if integrity tested successfully
-        */
-       bool (*check)(integrity_checker_t *this, char *name, void *sym);
-
-       /**
-        * Destroy a integrity_checker_t.
-        */
-       void (*destroy)(integrity_checker_t *this);
-};
-
-/**
- * Create a integrity_checker instance.
- *
- * @param checksum_library             library containing checksums
- */
-integrity_checker_t *integrity_checker_create(char *checksum_library);
-
-#endif /** INTEGRITY_CHECKER_H_ @}*/
index 557a7a0..ad31c1b 100644 (file)
@@ -84,7 +84,6 @@
 #include "utils.h"
 #include "chunk.h"
 #include "settings.h"
-#include "integrity_checker.h"
 #include "networking/host_resolver.h"
 #include "processing/processor.h"
 #include "processing/scheduler.h"
@@ -95,6 +94,7 @@
 #include "credentials/credential_factory.h"
 #include "credentials/credential_manager.h"
 #include "credentials/cred_encoding.h"
+#include "utils/integrity_checker.h"
 #include "utils/leak_detective.h"
 #include "plugins/plugin_loader.h"
 
index 007ef6a..1033695 100644 (file)
 
 #include <debug.h>
 #include <library.h>
-#include <integrity_checker.h>
 #include <collections/hashtable.h>
 #include <collections/linked_list.h>
 #include <plugins/plugin.h>
+#include <utils/integrity_checker.h>
 
 typedef struct private_plugin_loader_t private_plugin_loader_t;
 typedef struct plugin_entry_t plugin_entry_t;
diff --git a/src/libstrongswan/utils/integrity_checker.c b/src/libstrongswan/utils/integrity_checker.c
new file mode 100644 (file)
index 0000000..e962aba
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2009 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ */
+
+#define _GNU_SOURCE
+
+#include "integrity_checker.h"
+
+#include <dlfcn.h>
+#include <link.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "debug.h"
+#include "library.h"
+
+typedef struct private_integrity_checker_t private_integrity_checker_t;
+
+/**
+ * Private data of an integrity_checker_t object.
+ */
+struct private_integrity_checker_t {
+
+       /**
+        * Public integrity_checker_t interface.
+        */
+       integrity_checker_t public;
+
+       /**
+        * dlopen handle to checksum library
+        */
+       void *handle;
+
+       /**
+        * checksum array
+        */
+       integrity_checksum_t *checksums;
+
+       /**
+        * number of checksums in array
+        */
+       int checksum_count;
+};
+
+METHOD(integrity_checker_t, build_file, u_int32_t,
+       private_integrity_checker_t *this, char *file, size_t *len)
+{
+       u_int32_t checksum;
+       chunk_t contents;
+       struct stat sb;
+       void *addr;
+       int fd;
+
+       fd = open(file, O_RDONLY);
+       if (fd == -1)
+       {
+               DBG1(DBG_LIB, "  opening '%s' failed: %s", file, strerror(errno));
+               return 0;
+       }
+
+       if (fstat(fd, &sb) == -1)
+       {
+               DBG1(DBG_LIB, "  getting file size of '%s' failed: %s", file,
+                        strerror(errno));
+               close(fd);
+               return 0;
+       }
+
+       addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+       if (addr == MAP_FAILED)
+       {
+               DBG1(DBG_LIB, "  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);
+
+       munmap(addr, sb.st_size);
+       close(fd);
+
+       return checksum;
+}
+
+/**
+ * dl_iterate_phdr callback function
+ */
+static int callback(struct dl_phdr_info *dlpi, size_t size, Dl_info *dli)
+{
+       /* We are looking for the dlpi_addr matching the address of our dladdr().
+        * dl_iterate_phdr() returns such an address for other (unknown) objects
+        * in very rare cases (e.g. in a chrooted gentoo, but only if
+        * the checksum_builder is invoked by 'make'). As a workaround, we filter
+        * objects by dlpi_name; valid objects have a library name.
+        */
+       if (dli->dli_fbase == (void*)dlpi->dlpi_addr &&
+               dlpi->dlpi_name && *dlpi->dlpi_name)
+       {
+               int i;
+
+               for (i = 0; i < dlpi->dlpi_phnum; i++)
+               {
+                       const ElfW(Phdr) *sgmt = &dlpi->dlpi_phdr[i];
+
+                       /* we are interested in the executable LOAD segment */
+                       if (sgmt->p_type == PT_LOAD && (sgmt->p_flags & PF_X))
+                       {
+                               /* safe begin of segment in dli_fbase */
+                               dli->dli_fbase = (void*)sgmt->p_vaddr + dlpi->dlpi_addr;
+                               /* safe end of segment in dli_saddr */
+                               dli->dli_saddr = dli->dli_fbase + sgmt->p_memsz;
+                               return 1;
+                       }
+               }
+       }
+       return 0;
+}
+
+METHOD(integrity_checker_t, build_segment, u_int32_t,
+       private_integrity_checker_t *this, void *sym, size_t *len)
+{
+       chunk_t segment;
+       Dl_info dli;
+
+       if (dladdr(sym, &dli) == 0)
+       {
+               DBG1(DBG_LIB, "  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(DBG_LIB, "  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);
+}
+
+/**
+ * Find a checksum by its name
+ */
+static integrity_checksum_t *find_checksum(private_integrity_checker_t *this,
+                                                                                  char *name)
+{
+       int i;
+
+       for (i = 0; i < this->checksum_count; i++)
+       {
+               if (streq(this->checksums[i].name, name))
+               {
+                       return &this->checksums[i];
+               }
+       }
+       return NULL;
+}
+
+METHOD(integrity_checker_t, check_file, bool,
+       private_integrity_checker_t *this, char *name, char *file)
+{
+       integrity_checksum_t *cs;
+       u_int32_t sum;
+       size_t len = 0;
+
+       cs = find_checksum(this, name);
+       if (!cs)
+       {
+               DBG1(DBG_LIB, "  '%s' file checksum not found", name);
+               return FALSE;
+       }
+       sum = build_file(this, file, &len);
+       if (!sum)
+       {
+               return FALSE;
+       }
+       if (cs->file_len != len)
+       {
+               DBG1(DBG_LIB, "  invalid '%s' file size: %u bytes, expected %u bytes",
+                        name, len, cs->file_len);
+               return FALSE;
+       }
+       if (cs->file != sum)
+       {
+               DBG1(DBG_LIB, "  invalid '%s' file checksum: %08x, expected %08x",
+                        name, sum, cs->file);
+               return FALSE;
+       }
+       DBG2(DBG_LIB, "  valid '%s' file checksum: %08x", name, sum);
+       return TRUE;
+}
+
+METHOD(integrity_checker_t, check_segment, bool,
+       private_integrity_checker_t *this, char *name, void *sym)
+{
+       integrity_checksum_t *cs;
+       u_int32_t sum;
+       size_t len = 0;
+
+       cs = find_checksum(this, name);
+       if (!cs)
+       {
+               DBG1(DBG_LIB, "  '%s' segment checksum not found", name);
+               return FALSE;
+       }
+       sum = build_segment(this, sym, &len);
+       if (!sum)
+       {
+               return FALSE;
+       }
+       if (cs->segment_len != len)
+       {
+               DBG1(DBG_LIB, "  invalid '%s' segment size: %u bytes,"
+                        " expected %u bytes", name, len, cs->segment_len);
+               return FALSE;
+       }
+       if (cs->segment != sum)
+       {
+               DBG1(DBG_LIB, "  invalid '%s' segment checksum: %08x, expected %08x",
+                        name, sum, cs->segment);
+               return FALSE;
+       }
+       DBG2(DBG_LIB, "  valid '%s' segment checksum: %08x", name, sum);
+       return TRUE;
+}
+
+METHOD(integrity_checker_t, check, bool,
+       private_integrity_checker_t *this, char *name, void *sym)
+{
+       Dl_info dli;
+
+       if (dladdr(sym, &dli) == 0)
+       {
+               DBG1(DBG_LIB, "unable to locate symbol: %s", dlerror());
+               return FALSE;
+       }
+       if (!check_file(this, name, (char*)dli.dli_fname))
+       {
+               return FALSE;
+       }
+       if (!check_segment(this, name, sym))
+       {
+               return FALSE;
+       }
+       return TRUE;
+}
+
+METHOD(integrity_checker_t, destroy, void,
+       private_integrity_checker_t *this)
+{
+       if (this->handle)
+       {
+               dlclose(this->handle);
+       }
+       free(this);
+}
+
+/**
+ * See header
+ */
+integrity_checker_t *integrity_checker_create(char *checksum_library)
+{
+       private_integrity_checker_t *this;
+
+       INIT(this,
+               .public = {
+                       .check_file = _check_file,
+                       .build_file = _build_file,
+                       .check_segment = _check_segment,
+                       .build_segment = _build_segment,
+                       .check = _check,
+                       .destroy = _destroy,
+               },
+       );
+
+       if (checksum_library)
+       {
+               this->handle = dlopen(checksum_library, RTLD_LAZY);
+               if (this->handle)
+               {
+                       int *checksum_count;
+
+                       this->checksums = dlsym(this->handle, "checksums");
+                       checksum_count = dlsym(this->handle, "checksum_count");
+                       if (this->checksums && checksum_count)
+                       {
+                               this->checksum_count = *checksum_count;
+                       }
+                       else
+                       {
+                               DBG1(DBG_LIB, "checksum library '%s' invalid",
+                                        checksum_library);
+                       }
+               }
+               else
+               {
+                       DBG1(DBG_LIB, "loading checksum library '%s' failed",
+                                checksum_library);
+               }
+       }
+       return &this->public;
+}
+
diff --git a/src/libstrongswan/utils/integrity_checker.h b/src/libstrongswan/utils/integrity_checker.h
new file mode 100644 (file)
index 0000000..f999b9a
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2009 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup integrity_checker integrity_checker
+ * @{ @ingroup utils
+ */
+
+#ifndef INTEGRITY_CHECKER_H_
+#define INTEGRITY_CHECKER_H_
+
+#include "../utils.h"
+
+typedef struct integrity_checker_t integrity_checker_t;
+typedef struct integrity_checksum_t integrity_checksum_t;
+
+/**
+ * Struct to hold a precalculated checksum, implemented in the checksum library.
+ */
+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;
+};
+
+/**
+ * Code integrity checker to detect non-malicious file manipulation.
+ *
+ * The integrity checker reads the checksums from a separate library
+ * libchecksum.so to compare the checksums.
+ */
+struct integrity_checker_t {
+
+       /**
+        * Check the integrity of a file on disk.
+        *
+        * @param name          name to lookup checksum
+        * @param file          path to file
+        * @return                      TRUE if integrity tested successfully
+        */
+       bool (*check_file)(integrity_checker_t *this, char *name, char *file);
+
+       /**
+        * 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, size_t *len);
+
+       /**
+        * Check the integrity of the code segment in memory.
+        *
+        * @param name          name to lookup checksum
+        * @param sym           a symbol in the segment to check
+        * @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, size_t *len);
+
+       /**
+        * Check both, on disk file integrity and loaded segment.
+        *
+        * @param name          name to lookup checksum
+        * @param sym           a symbol to look up library and segment
+        * @return                      TRUE if integrity tested successfully
+        */
+       bool (*check)(integrity_checker_t *this, char *name, void *sym);
+
+       /**
+        * Destroy a integrity_checker_t.
+        */
+       void (*destroy)(integrity_checker_t *this);
+};
+
+/**
+ * Create a integrity_checker instance.
+ *
+ * @param checksum_library             library containing checksums
+ */
+integrity_checker_t *integrity_checker_create(char *checksum_library);
+
+#endif /** INTEGRITY_CHECKER_H_ @}*/