Use an explicit plugin list instead of the unrealible "find" to build checksums
[strongswan.git] / src / checksum / checksum_builder.c
1 /*
2 * Copyright (C) 2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil, Switzerland
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #define _GNU_SOURCE
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <dlfcn.h>
20
21 #include <library.h>
22 #include <utils/enumerator.h>
23
24 /* we need to fake the pluto symbol to dlopen() the xauth plugin */
25 void *pluto;
26
27 /**
28 * Integrity checker
29 */
30 integrity_checker_t *integrity;
31
32 /**
33 * Create the checksum of a binary, using name and a symbol name
34 */
35 static void build_checksum(char *path, char *name, char *sname)
36 {
37 void *handle, *symbol;
38 u_int32_t fsum, ssum;
39 size_t fsize = 0;
40 size_t ssize = 0;
41
42 fsum = integrity->build_file(integrity, path, &fsize);
43 ssum = 0;
44 if (sname)
45 {
46 handle = dlopen(path, RTLD_LAZY);
47 if (handle)
48 {
49 symbol = dlsym(handle, sname);
50 if (symbol)
51 {
52 ssum = integrity->build_segment(integrity, symbol, &ssize);
53 }
54 else
55 {
56 fprintf(stderr, "symbol lookup failed: %s\n", dlerror());
57 }
58 dlclose(handle);
59 }
60 else
61 {
62 fprintf(stderr, "dlopen failed: %s\n", dlerror());
63 }
64 }
65 printf("\t{\"%-20s%7u, 0x%08x, %6u, 0x%08x},\n",
66 name, fsize, fsum, ssize, ssum);
67 fprintf(stderr, "\"%-20s%7u / 0x%08x %6u / 0x%08x\n",
68 name, fsize, fsum, ssize, ssum);
69 }
70
71 /**
72 * Build checksums for a set of plugins in a given path prefix
73 */
74 static void build_plugin_checksums(char *plugins, char *prefix)
75 {
76 enumerator_t *enumerator;
77 char *plugin, path[256], under[128], sname[128], name[128];
78
79 enumerator = enumerator_create_token(plugins, " ", " ");
80 while (enumerator->enumerate(enumerator, &plugin))
81 {
82 snprintf(under, sizeof(under), "%s", plugin);
83 translate(under, "-", "_");
84 snprintf(path, sizeof(path), "%s/%s/.libs/libstrongswan-%s.so",
85 prefix, under, plugin);
86 snprintf(sname, sizeof(sname), "%s_plugin_create", under);
87 snprintf(name, sizeof(name), "%s\",", plugin);
88 build_checksum(path, name, sname);
89 }
90 enumerator->destroy(enumerator);
91 }
92
93 /**
94 * Build checksums for a binary/library found at path
95 */
96 static void build_binary_checksum(char *path)
97 {
98 char *binary, *pos, name[128], sname[128];
99
100 binary = strrchr(path, '/');
101 if (binary)
102 {
103 binary++;
104 pos = strrchr(binary, '.');
105 if (pos && streq(pos, ".so"))
106 {
107 snprintf(name, sizeof(name), "%.*s\",", pos - binary, binary);
108 if (streq(name, "libstrongswan\","))
109 {
110 snprintf(sname, sizeof(sname), "%s", "library_init");
111 }
112 else
113 {
114 snprintf(sname, sizeof(sname), "%.*s_init", pos - binary, binary);
115 }
116 build_checksum(path, name, sname);
117 }
118 else
119 {
120 snprintf(name, sizeof(name), "%s\",", binary);
121 build_checksum(path, name, NULL);
122 }
123 }
124 }
125
126 int main(int argc, char* argv[])
127 {
128 int i;
129
130 /* avoid confusing leak reports in build process */
131 setenv("LEAK_DETECTIVE_DISABLE", "1", 0);
132 library_init(NULL);
133 atexit(library_deinit);
134
135 integrity = integrity_checker_create(NULL);
136
137 printf("/**\n");
138 printf(" * checksums of files and loaded code segments.\n");
139 printf(" * created by %s\n", argv[0]);
140 printf(" */\n");
141 printf("\n");
142 printf("#include <library.h>\n");
143 printf("\n");
144 printf("integrity_checksum_t checksums[] = {\n");
145 fprintf(stderr, "integrity test data:\n");
146 fprintf(stderr, "module name, file size / checksum segment size / checksum\n");
147 for (i = 1; i < argc; i++)
148 {
149 build_binary_checksum(argv[i]);
150 }
151 build_plugin_checksums(S_PLUGINS, S_PATH);
152 build_plugin_checksums(H_PLUGINS, H_PATH);
153 build_plugin_checksums(P_PLUGINS, P_PATH);
154 build_plugin_checksums(C_PLUGINS, C_PATH);
155
156 printf("};\n");
157 printf("\n");
158 printf("int checksum_count = countof(checksums);\n");
159 printf("\n");
160 integrity->destroy(integrity);
161
162 exit(0);
163 }
164