Force link of checksum builder against libhydra/libcharon
[strongswan.git] / src / checksum / checksum_builder.c
index b917e11..94b04c6 100644 (file)
  * for more details.
  */
 
+#define _GNU_SOURCE
 #include <stdlib.h>
 #include <stdio.h>
 #include <dlfcn.h>
 
 #include <library.h>
+#include <hydra.h>
+#include <daemon.h>
+#include <utils/enumerator.h>
 
-/* we need to fake some charon symbols to dlopen() its plugins */
-void *eap_type_names, *auth_class_names, *charon, *protocol_id_names, 
-*action_names, *ipsec_mode_names, *ike_sa_state_names, *child_sa_state_names,
-*proposal_create_default, *peer_cfg_create, *ike_cfg_create, *child_cfg_create,
-*traffic_selector_create_dynamic, *callback_job_create, *delete_ike_sa_job_create,
-*eap_type_from_string, *auth_cfg_create, *proposal_create_from_string,
-*traffic_selector_create_from_subnet, *traffic_selector_create_from_bytes,
-*eap_payload_create_data, *ike_sa_create, *child_sa_create, *policy_dir_names,
-*controller_cb_empty, *proposal_create, *ipcomp_transform_names,
-*traffic_selector_create_from_string, *update_sa_job_create, *ike_sa_id_create,
-*rekey_child_sa_job_create, *roam_job_create, *migrate_job_create,
-*acquire_job_create, *delete_child_sa_job_create, *debug_names;
+/* we need to fake the pluto symbol to dlopen() the xauth plugin */
+void *pluto;
 
-int main(int argc, char* argv[])
+/**
+ * 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)
 {
-       int i;
-       integrity_checker_t *integrity;
-       
-       /* avoid confusing leak reports in build process */
-       setenv("LEAK_DETECTIVE_DISABLE", "1", 0);
-       library_init(NULL);
-       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");
-       for (i = 1; i < argc; i++)
+       void *handle, *symbol;
+       u_int32_t fsum, ssum;
+       size_t fsize = 0;
+       size_t ssize = 0;
+
+       fsum = integrity->build_file(integrity, path, &fsize);
+       ssum = 0;
+       if (sname)
        {
-               char *name, *path, *sname;
-               void *handle, *symbol;
-               u_int32_t fsum, ssum;
-               
-               path = argv[i];
-               
-               if ((name = strstr(path, "libstrongswan-")))
-               {
-                       name = strdup(name + strlen("libstrongswan-"));
-                       name[strlen(name) - 3] = '"';
-                       name[strlen(name) - 2] = ',';
-                       name[strlen(name) - 1] = '\0';
-                       sname = "plugin_create";
-               }
-               else if (strstr(path, "libstrongswan.so"))
-               {
-                       name = strdup("libstrongswan\",");
-                       sname = "library_init";
-               }
-               else
-               {
-                       fprintf(stderr, "don't know how to handle '%s', ignored", path);
-                       continue;
-               }
-               
-               fsum = integrity->build_file(integrity, path);
-               ssum = 0;
                handle = dlopen(path, RTLD_LAZY);
                if (handle)
                {
                        symbol = dlsym(handle, sname);
                        if (symbol)
                        {
-                               ssum = integrity->build_segment(integrity, symbol);
+                               ssum = integrity->build_segment(integrity, symbol, &ssize);
                        }
                        else
                        {
@@ -99,16 +63,114 @@ int main(int argc, char* argv[])
                {
                        fprintf(stderr, "dlopen failed: %s\n", dlerror());
                }
-               
-               printf("\t{\"%-20s0x%08x, 0x%08x},\n", name, fsum, ssum);
-               free(name);
        }
+       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);
+}
+
+/**
+ * Build checksums for a set of plugins in a given path prefix
+ */
+static void build_plugin_checksums(char *plugins, char *prefix)
+{
+       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/%s/.libs/libstrongswan-%s.so",
+                                prefix, under, 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\",", pos - binary, binary);
+                       if (streq(name, "libstrongswan\","))
+                       {
+                               snprintf(sname, sizeof(sname), "%s", "library_init");
+                       }
+                       else
+                       {
+                               snprintf(sname, sizeof(sname), "%.*s_init", 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 libhydra/libcharon */
+       hydra = NULL;
+       charon = NULL;
+
+       /* avoid confusing leak reports in build process */
+       setenv("LEAK_DETECTIVE_DISABLE", "1", 0);
+       library_init(NULL);
+       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]);
+       }
+       build_plugin_checksums(S_PLUGINS, S_PATH);
+#ifdef H_PLUGINS
+       build_plugin_checksums(H_PLUGINS, H_PATH);
+#endif
+#ifdef P_PLUGINS
+       build_plugin_checksums(P_PLUGINS, P_PATH);
+#endif
+#ifdef C_PLUGINS
+       build_plugin_checksums(C_PLUGINS, C_PATH);
+#endif
+
        printf("};\n");
        printf("\n");
        printf("int checksum_count = countof(checksums);\n");
        printf("\n");
        integrity->destroy(integrity);
-       
+
        exit(0);
 }