read IMC/IMV configurations from /etc/tnc_config
[strongswan.git] / src / libcharon / plugins / tnc_imc / tnc_imc_plugin.c
1 /*
2 * Copyright (C) 2010 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
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 #include "tnc_imc_plugin.h"
17 #include "tnc_imc_manager.h"
18 #include "tnc_imc.h"
19
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/mman.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <fcntl.h>
26
27 #include <daemon.h>
28 #include <utils/lexparser.h>
29
30 /**
31 * load IMCs from a configuration file
32 */
33 static bool load_imcs(char *filename)
34 {
35 int fd, line_nr = 0;
36 chunk_t src, line;
37 struct stat sb;
38 void *addr;
39
40 DBG1(DBG_TNC, "loading IMCs from '%s'", filename);
41 fd = open(filename, O_RDONLY);
42 if (fd == -1)
43 {
44 DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename,
45 strerror(errno));
46 return FALSE;
47 }
48 if (fstat(fd, &sb) == -1)
49 {
50 DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename,
51 strerror(errno));
52 close(fd);
53 return FALSE;
54 }
55 addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
56 if (addr == MAP_FAILED)
57 {
58 DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno));
59 close(fd);
60 return FALSE;
61 }
62 src = chunk_create(addr, sb.st_size);
63
64 while (fetchline(&src, &line))
65 {
66 char *name, *path;
67 chunk_t token;
68 imc_t *imc;
69
70 line_nr++;
71
72 /* skip comments or empty lines */
73 if (*line.ptr == '#' || !eat_whitespace(&line))
74 {
75 continue;
76 }
77
78 /* determine keyword */
79 if (!extract_token(&token, ' ', &line))
80 {
81 DBG1(DBG_TNC, "line %d: keyword must be followed by a space",
82 line_nr);
83 return FALSE;
84 }
85
86 /* only interested in IMCs */
87 if (!match("IMC", &token))
88 {
89 continue;
90 }
91
92 /* advance to the IMC name and extract it */
93 if (!extract_token(&token, '"', &line) ||
94 !extract_token(&token, '"', &line))
95 {
96 DBG1(DBG_TNC, "line %d: IMC name must be set in double quotes",
97 line_nr);
98 return FALSE;
99 }
100
101 /* copy the IMC name */
102 name = malloc(token.len + 1);
103 memcpy(name, token.ptr, token.len);
104 name[token.len] = '\0';
105
106 /* advance to the IMC path and extract it */
107 if (!eat_whitespace(&line))
108 {
109 DBG1(DBG_TNC, "line %d: IMC path is missing", line_nr);
110 free(name);
111 return FALSE;
112 }
113 if (!extract_token(&token, ' ', &line))
114 {
115 token = line;
116 }
117
118 /* copy the IMC path */
119 path = malloc(token.len + 1);
120 memcpy(path, token.ptr, token.len);
121 path[token.len] = '\0';
122
123 /* load and register IMC instance */
124 imc = tnc_imc_create(name, path);
125 if (!imc)
126 {
127 free(name);
128 free(path);
129 return FALSE;
130 }
131 if (!charon->imcs->add(charon->imcs, imc))
132 {
133 imc->destroy(imc);
134 return FALSE;
135 }
136 DBG1(DBG_TNC, "IMC \"%s\" loaded from '%s'", name, path);
137 }
138 munmap(addr, sb.st_size);
139 close(fd);
140 return TRUE;
141 }
142
143 METHOD(plugin_t, destroy, void,
144 tnc_imc_plugin_t *this)
145 {
146 charon->imcs->destroy(charon->imcs);
147 free(this);
148 }
149
150 /*
151 * see header file
152 */
153 plugin_t *tnc_imc_plugin_create()
154 {
155 char *tnc_config, *pref_lang;
156 tnc_imc_plugin_t *this;
157
158 INIT(this,
159 .plugin = {
160 .destroy = _destroy,
161 },
162 );
163
164 pref_lang = lib->settings->get_str(lib->settings,
165 "charon.plugins.tnc-imc.preferred_language", "en");
166 tnc_config = lib->settings->get_str(lib->settings,
167 "charon.plugins.tnc-imc.tnc_config", "/etc/tnc_config");
168
169 /* Create IMC manager */
170 charon->imcs = tnc_imc_manager_create();
171
172 /* Load IMCs and abort if not all instances initalize successfully */
173 if (!load_imcs(tnc_config))
174 {
175 charon->imcs->destroy(charon->imcs);
176 free(this);
177 return NULL;
178 }
179 return &this->plugin;
180 }
181