strongswan/src/checksum/checksum_builder.c

176 lines
4.2 KiB
C

/*
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil, Switzerland
*
* 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 <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <library.h>
#include <daemon.h>
#include <collections/enumerator.h>
/**
* 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 <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++)
{
build_binary_checksum(argv[i]);
}
#ifdef S_PLUGINS
build_plugin_checksums(S_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);
}