/* * Copyright (C) 2009 Martin Willi * HSR 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 . * * 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 #include #include #include #include #include /** * Integrity checker */ integrity_checker_t *integrity; /** * Create the checksum of a binary, using name and a symbol name */ static void build_checksum(char *path, char *name, char *sname) { void *handle, *symbol; uint32_t fsum, ssum; size_t fsize = 0; size_t ssize = 0; fsum = integrity->build_file(integrity, path, &fsize); ssum = 0; if (sname) { handle = dlopen(path, RTLD_LAZY); if (handle) { symbol = dlsym(handle, sname); if (symbol) { ssum = integrity->build_segment(integrity, symbol, &ssize); } else { fprintf(stderr, "symbol lookup failed: %s\n", dlerror()); } dlclose(handle); } else { fprintf(stderr, "dlopen failed: %s\n", dlerror()); } } printf("\t{\"%-25s%7u, 0x%08x, %6u, 0x%08x},\n", name, fsize, fsum, ssize, ssum); fprintf(stderr, "\"%-25s%7u / 0x%08x %6u / 0x%08x\n", name, fsize, fsum, ssize, ssum); } /** * Build checksums for a set of plugins */ static void build_plugin_checksums(char *plugins) { enumerator_t *enumerator; char *plugin, path[256], under[128], sname[128], name[128]; enumerator = enumerator_create_token(plugins, " ", " "); while (enumerator->enumerate(enumerator, &plugin)) { snprintf(under, sizeof(under), "%s", plugin); translate(under, "-", "_"); snprintf(path, sizeof(path), "%s/libstrongswan-%s.so", PLUGINDIR, plugin); snprintf(sname, sizeof(sname), "%s_plugin_create", under); snprintf(name, sizeof(name), "%s\",", plugin); build_checksum(path, name, sname); } enumerator->destroy(enumerator); } /** * Build checksums for a binary/library found at path */ static void build_binary_checksum(char *path) { char *binary, *pos, name[128], sname[128]; binary = strrchr(path, '/'); if (binary) { binary++; pos = strrchr(binary, '.'); if (pos && streq(pos, ".so")) { snprintf(name, sizeof(name), "%.*s\",", (int)(pos - binary), binary); if (streq(name, "libstrongswan\",")) { snprintf(sname, sizeof(sname), "%s", "library_init"); } else { snprintf(sname, sizeof(sname), "%.*s_init", (int)(pos - binary), binary); } build_checksum(path, name, sname); } else { snprintf(name, sizeof(name), "%s\",", binary); build_checksum(path, name, NULL); } } } int main(int argc, char* argv[]) { int i; /* forces link against libcharon, imports symbols needed to * dlopen plugins */ charon = NULL; /* avoid confusing leak reports in build process */ setenv("LEAK_DETECTIVE_DISABLE", "1", 0); /* don't use a strongswan.conf, forces integrity check to disabled */ library_init("", "checksum_builder"); atexit(library_deinit); integrity = integrity_checker_create(NULL); printf("/**\n"); printf(" * checksums of files and loaded code segments.\n"); printf(" * created by %s\n", argv[0]); printf(" */\n"); printf("\n"); printf("#include \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++) { build_binary_checksum(argv[i]); } #ifdef S_PLUGINS build_plugin_checksums(S_PLUGINS); #endif #ifdef P_PLUGINS build_plugin_checksums(P_PLUGINS); #endif #ifdef T_PLUGINS build_plugin_checksums(T_PLUGINS); #endif #ifdef C_PLUGINS build_plugin_checksums(C_PLUGINS); #endif printf("};\n"); printf("\n"); printf("int checksum_count = countof(checksums);\n"); printf("\n"); integrity->destroy(integrity); exit(0); }