Separated IMV session management from IMV policy database
[strongswan.git] / src / libimcv / imcv.c
1 /*
2 * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 */
14
15 #include "imcv.h"
16 #include "ietf/ietf_attr.h"
17 #include "ita/ita_attr.h"
18
19 #include <utils/debug.h>
20 #include <utils/utils.h>
21 #include <pen/pen.h>
22
23 #include <syslog.h>
24
25 #define IMCV_DEBUG_LEVEL 1
26 #define IMCV_DEFAULT_POLICY_SCRIPT "ipsec _imv_policy"
27
28
29 /**
30 * PA-TNC attribute manager
31 */
32 pa_tnc_attr_manager_t *imcv_pa_tnc_attributes;
33
34 /**
35 * Global list of IMV sessions
36 */
37 imv_session_manager_t *imcv_sessions;
38
39 /**
40 * Global IMV database
41 */
42 imv_database_t *imcv_db;
43
44 /**
45 * Reference count for libimcv
46 */
47 static refcount_t libimcv_ref = 0;
48
49 /**
50 * Reference count for libstrongswan
51 */
52 static refcount_t libstrongswan_ref = 0;
53
54 /**
55 * Global configuration of imcv dbg function
56 */
57 static int imcv_debug_level;
58 static bool imcv_stderr_quiet;
59
60 /**
61 * imvc dbg function
62 */
63 static void imcv_dbg(debug_t group, level_t level, char *fmt, ...)
64 {
65 int priority = LOG_INFO;
66 char buffer[8192];
67 char *current = buffer, *next;
68 va_list args;
69
70 if (level <= imcv_debug_level)
71 {
72 if (!imcv_stderr_quiet)
73 {
74 va_start(args, fmt);
75 fprintf(stderr, "[HSR] ");
76 vfprintf(stderr, fmt, args);
77 fprintf(stderr, "\n");
78 va_end(args);
79 }
80
81 /* write in memory buffer first */
82 va_start(args, fmt);
83 vsnprintf(buffer, sizeof(buffer), fmt, args);
84 va_end(args);
85
86 /* do a syslog with every line */
87 while (current)
88 {
89 next = strchr(current, '\n');
90 if (next)
91 {
92 *(next++) = '\0';
93 }
94 syslog(priority, "[HSR] %s\n", current);
95 current = next;
96 }
97 }
98 }
99
100 /**
101 * Described in header.
102 */
103 bool libimcv_init(bool is_imv)
104 {
105 /* initialize libstrongswan library only once */
106 if (lib)
107 {
108 /* did main program initialize libstrongswan? */
109 if (libstrongswan_ref == 0)
110 {
111 ref_get(&libstrongswan_ref);
112 }
113 }
114 else
115 {
116 /* we are the first to initialize libstrongswan */
117 if (!library_init(NULL, "libimcv"))
118 {
119 return FALSE;
120 }
121
122 /* set the debug level and stderr output */
123 imcv_debug_level = lib->settings->get_int(lib->settings,
124 "libimcv.debug_level", IMCV_DEBUG_LEVEL);
125 imcv_stderr_quiet = lib->settings->get_int(lib->settings,
126 "libimcv.stderr_quiet", FALSE);
127
128 /* activate the imcv debugging hook */
129 dbg = imcv_dbg;
130 openlog("imcv", 0, LOG_DAEMON);
131
132 if (!lib->plugins->load(lib->plugins,
133 lib->settings->get_str(lib->settings, "libimcv.load",
134 "random nonce gmp pubkey x509")))
135 {
136 library_deinit();
137 return FALSE;
138 }
139 }
140 ref_get(&libstrongswan_ref);
141
142 lib->settings->add_fallback(lib->settings, "%s.imcv", "libimcv", lib->ns);
143 lib->settings->add_fallback(lib->settings, "%s.plugins", "libimcv.plugins",
144 lib->ns);
145
146 if (libimcv_ref == 0)
147 {
148 char *uri, *script;
149
150 /* initialize the PA-TNC attribute manager */
151 imcv_pa_tnc_attributes = pa_tnc_attr_manager_create();
152 imcv_pa_tnc_attributes->add_vendor(imcv_pa_tnc_attributes, PEN_IETF,
153 ietf_attr_create_from_data, ietf_attr_names);
154 imcv_pa_tnc_attributes->add_vendor(imcv_pa_tnc_attributes, PEN_ITA,
155 ita_attr_create_from_data, ita_attr_names);
156
157 if (is_imv)
158 {
159 /* instantiate global IMV session manager */
160 imcv_sessions = imv_session_manager_create();
161
162 /* instantiate and attach global IMV database if URI is valid */
163 uri = lib->settings->get_str(lib->settings,
164 "%s.imcv.database", NULL, lib->ns);
165 script = lib->settings->get_str(lib->settings,
166 "%s.imcv.policy_script", IMCV_DEFAULT_POLICY_SCRIPT,
167 lib->ns);
168 if (uri)
169 {
170 imcv_db = imv_database_create(uri, script);
171 }
172 }
173 DBG1(DBG_LIB, "libimcv initialized");
174 }
175 ref_get(&libimcv_ref);
176
177 return TRUE;
178 }
179
180 /**
181 * Described in header.
182 */
183 void libimcv_deinit(void)
184 {
185 if (ref_put(&libimcv_ref))
186 {
187 imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_IETF);
188 imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_ITA);
189 DESTROY_IF(imcv_pa_tnc_attributes);
190 imcv_pa_tnc_attributes = NULL;
191 DESTROY_IF(imcv_db);
192 DESTROY_IF(imcv_sessions);
193 DBG1(DBG_LIB, "libimcv terminated");
194 }
195 if (ref_put(&libstrongswan_ref))
196 {
197 library_deinit();
198 }
199 }
200