/* * Copyright (C) 2011 Andreas Steffen * 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. */ #include "tnc.h" #include #include #include #include #include #include #include #include typedef struct private_tnc_t private_tnc_t; typedef tnccs_manager_t *(*tnc_create_tnccs_manager_t)(void); typedef imc_manager_t *(*tnc_create_imc_manager_t)(void); typedef imv_manager_t *(*tnc_create_imv_manager_t)(void); /** * Private additions to tnc_t. */ struct private_tnc_t { /** * Public members of tnc_t. */ tnc_t public; }; /** * Single instance of tnc_t. */ tnc_t *tnc; /** * Described in header. */ void libtnccs_init(void) { private_tnc_t *this; INIT(this, .public = { }, ); tnc = &this->public; } /** * Described in header. */ void libtnccs_deinit(void) { private_tnc_t *this = (private_tnc_t*)tnc; free(this); tnc = NULL; } static bool load_imcvs_from_config(char *filename, bool is_imc) { int fd, line_nr = 0; chunk_t src, line; struct stat sb; void *addr; char *label; label = is_imc ? "IMC" : "IMV"; DBG1(DBG_TNC, "loading %ss from '%s'", label, filename); fd = open(filename, O_RDONLY); if (fd == -1) { DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename, strerror(errno)); return FALSE; } if (fstat(fd, &sb) == -1) { DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename, strerror(errno)); close(fd); return FALSE; } addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) { DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno)); close(fd); return FALSE; } src = chunk_create(addr, sb.st_size); while (fetchline(&src, &line)) { char *name, *path; bool success; chunk_t token; line_nr++; /* skip comments or empty lines */ if (*line.ptr == '#' || !eat_whitespace(&line)) { continue; } /* determine keyword */ if (!extract_token(&token, ' ', &line)) { DBG1(DBG_TNC, "line %d: keyword must be followed by a space", line_nr); return FALSE; } /* only interested in IMCs or IMVs depending on label */ if (!match(label, &token)) { continue; } /* advance to the IMC/IMV name and extract it */ if (!extract_token(&token, '"', &line) || !extract_token(&token, '"', &line)) { DBG1(DBG_TNC, "line %d: %s name must be set in double quotes", line_nr, label); return FALSE; } /* copy the IMC/IMV name */ name = malloc(token.len + 1); memcpy(name, token.ptr, token.len); name[token.len] = '\0'; /* advance to the IMC/IMV path and extract it */ if (!eat_whitespace(&line)) { DBG1(DBG_TNC, "line %d: %s path is missing", line_nr, label); free(name); return FALSE; } if (!extract_token(&token, ' ', &line)) { token = line; } /* copy the IMC/IMV path */ path = malloc(token.len + 1); memcpy(path, token.ptr, token.len); path[token.len] = '\0'; /* load and register an IMC/IMV instance */ if (is_imc) { success = tnc->imcs->load(tnc->imcs, name, path); } else { success = tnc->imvs->load(tnc->imvs, name, path); } if (!success) { return FALSE; } } munmap(addr, sb.st_size); close(fd); return TRUE; } /** * Described in header. */ bool tnc_manager_register(plugin_t *plugin, plugin_feature_t *feature, bool reg, void *data) { bool load_imcvs = FALSE; bool is_imc = FALSE; if (feature->type == FEATURE_CUSTOM) { if (streq(feature->arg.custom, "tnccs-manager")) { if (reg) { tnc->tnccs = ((tnc_create_tnccs_manager_t)data)(); } else { tnc->tnccs->destroy(tnc->tnccs); tnc->tnccs = NULL; } } else if (streq(feature->arg.custom, "imc-manager")) { if (reg) { tnc->imcs = ((tnc_create_imc_manager_t)data)(); is_imc = TRUE; load_imcvs = TRUE; } else { tnc->imcs->destroy(tnc->imcs); tnc->imcs = NULL; } } else if (streq(feature->arg.custom, "imv-manager")) { if (reg) { tnc->imvs = ((tnc_create_imv_manager_t)data)(); is_imc = FALSE; load_imcvs = TRUE; } else { tnc->imvs->destroy(tnc->imvs); tnc->imvs = NULL; } } else { return FALSE; } if (load_imcvs) { char *tnc_config; tnc_config = lib->settings->get_str(lib->settings, "libtnccs.tnc_config", "/etc/tnc_config"); if (!load_imcvs_from_config(tnc_config, is_imc)) { if (is_imc) { tnc->imcs->destroy(tnc->imcs); tnc->imcs = NULL; } else { tnc->imvs->destroy(tnc->imvs); tnc->imvs = NULL; } return FALSE; } } } return TRUE; }