1 /* $Id$
2 *
3 * Lasso - A free implementation of the Liberty Alliance specifications.
4 *
5 * Copyright (C) 2004-2007 Entr'ouvert
6 * http://lasso.entrouvert.org
7 *
8 * Authors: See AUTHORS file in top-level directory.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24 /**
25 * SECTION:lasso
26 * @short_description: Initialization functions
27 *
28 * <sec2>
29 * <title>Environment variables</title>
30 * <para>
31 * <literal>LASSO_FLAG</literal> is an environment variable containing white-space separated values
32 * which allows to modify the behaviour of lasso. To negate the effect of one of
33 * the value, just add <literal>no-</literal> in front of its name. The flag are also modifiable
34 * using the lasso_set_flag() function. Those values are:
35 *
36 * <informaltable frame="non">
37 * <tgroup cols="2">
38 * <tbody>
39 * <rows>
40 * <entry><literal>no-verify-signature</literal></entry>
41 * <entry><para>Disable the validation of signatures on all message, usually for
42 * debugging pupose</para></entry>
43 * </rows>
44 * <rows>
45 * <entry><literal>memory-debug</literal></entry>
46 * <entry><para>Enable the tracing of nodes allocation, deallocation and initialization.</para></entry>
47 * </rows>
48 * <rows id="strict-checking">
49 * <entry><literal>strict-checking</literal></entry>
50 * <entry><para>Enable checking which were not done in previous version of Lasso, like matching <literal>ResponseTo</literal> attributes of response messages to the identifier of the request.</para></entry>
51 * </rows>
52 * <rows>
53 * <entry><literal>no-add-signature</literal></entry>
54 * <entry><para>Disable all signatures</para></entry>
55 * </rows>
56 * <rows>
57 * <entry><literal>no-sign-messages</literal></entry>
58 * <entry><para>Disable signatures on messages.</para></entry>
59 * </rows>
60 * <rows>
61 * <entry><literal>no-sign-messages</literal></entry>
62 * <entry><para>Disable signatures on messages.</para></entry>
63 * </rows>
64 * <rows>
65 * <entry><literal>pem-public-key</literal></entry>
66 * <entry><para>Allow PEM key in ds:KeyValue nodes, it's outside the XMLSig specification.</para></entry>
67 * </rows>
68 * </tbody>
69 * </tgroup>
70 * </informaltable>
71 * </para>
72 * </sec2>
73 **/
74
75 #include <stdlib.h> /* getenv */
76 #include <string.h> /* strcmp */
77 #include <xmlsec/xmlsec.h>
78 #include <xmlsec/crypto.h>
79 #include <xmlsec/errors.h>
80 #include <libxslt/xslt.h>
81 #include <config.h>
82 #include "lasso.h"
83 #include "lasso_config.h"
84 #include "debug.h"
85 #include "backward_comp.h"
86 #include "registry-private.h"
87 #include "xml/private.h"
88 #include "utils.h"
89
90 /* Set to true, it forces lasso_provider_verify_signature and lasso_query_verify_signature to always
91 * return TRUE. */
92 gboolean lasso_flag_verify_signature = TRUE;
93 /* Set to true, it activates debugging code for LassoNode freeing */
94 gboolean lasso_flag_memory_debug = FALSE;
95 /* set to true, it activates more strict validation of messages */
96 gboolean lasso_flag_strict_checking = FALSE;
97 /* set to false, it does not sign messages */
98 gboolean lasso_flag_add_signature = TRUE;
99 static void lasso_flag_parse_environment_variable();
100 /* do not sign messages */
101 gboolean lasso_flag_sign_messages = TRUE;
102 /* thin sessions */
103 gboolean lasso_flag_thin_sessions = FALSE;
104 /* PEM public key */
105 gboolean lasso_flag_pem_public_key = FALSE;
106
107 #ifndef LASSO_FLAG_ENV_VAR
108 #define LASSO_FLAG_ENV_VAR "LASSO_FLAG"
109 #endif
110
111 #if defined _MSC_VER
112 HINSTANCE g_hModule = NULL;
113
114 /**
115 * DllMain:
116 * @hinstDLL: hnadle to the DLL module
117 * @fdwReason: reason value of the DLL call
118 * @lpvReserved: use is unknown.
119 *
120 * Called when the DLL is attached or detached by a program.
121 *
122 * Return value: %TRUE if everything is OK
123 **/
124 BOOL WINAPI
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)125 DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
126 {
127 if (fdwReason == DLL_PROCESS_ATTACH)
128 {
129 DisableThreadLibraryCalls(hinstDLL);
130 g_hModule = hinstDLL;
131 }
132 return TRUE;
133 }
134 #endif
135
136 #include "types.c"
137
138 static void
lasso_xml_structured_error_func(G_GNUC_UNUSED void * user_data,xmlErrorPtr error)139 lasso_xml_structured_error_func(G_GNUC_UNUSED void *user_data, xmlErrorPtr error)
140 {
141 g_log("libxml2", G_LOG_LEVEL_DEBUG, "libxml2: %s", error->message);
142 }
143
144 void
lasso_xmlsec_errors_callback(const char * file G_GNUC_UNUSED,int line G_GNUC_UNUSED,const char * func G_GNUC_UNUSED,const char * errorObject G_GNUC_UNUSED,const char * errorSubject G_GNUC_UNUSED,int reason G_GNUC_UNUSED,const char * msg)145 lasso_xmlsec_errors_callback(const char *file G_GNUC_UNUSED, int line G_GNUC_UNUSED, const char *func G_GNUC_UNUSED,
146 const char *errorObject G_GNUC_UNUSED, const char *errorSubject G_GNUC_UNUSED, int reason G_GNUC_UNUSED,
147 const char *msg)
148 {
149 g_log("libxmlsec", G_LOG_LEVEL_DEBUG, "libxmlsec: %s:%d:%s:%s:%s:%s:%s", file, line, func, errorObject, errorSubject, xmlSecErrorsGetMsg(reason), msg);
150 }
151
152 /**
153 * lasso_init:
154 *
155 * Initializes Lasso library.
156 *
157 * Return value: 0 on success; or a negative value otherwise.
158 **/
lasso_init()159 int lasso_init()
160 {
161 int i;
162
163 #ifndef GLIB_VERSION_2_36
164 g_type_init();
165 #endif
166
167 /* Init Lasso classes */
168 for (i=0; functions[i]; i++)
169 functions[i]();
170
171 /* Init libxml and libxslt libraries */
172 xmlInitParser();
173 /*LIBXML_TEST_VERSION*/
174 /* xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; */
175 /* xmlSubstituteEntitiesDefault(1); */
176
177 /* Init xmlsec library */
178 if (xmlSecInit() < 0) {
179 message(G_LOG_LEVEL_CRITICAL, "XMLSec initialization failed.");
180 return LASSO_ERROR_UNDEFINED;
181 }
182
183 /* Load default crypto engine if we are supporting dynamic
184 * loading for xmlsec-crypto libraries. Use the crypto library
185 * name ("openssl", "nss", etc.) to load corresponding
186 * xmlsec-crypto library.
187 */
188 #ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
189 if (xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) {
190 message(G_LOG_LEVEL_CRITICAL,
191 "Unable to load default xmlsec-crypto library. Make sure"
192 "that you have it installed and check shared libraries path"
193 "(LD_LIBRARY_PATH) environment variable.");
194 return LASSO_ERROR_UNDEFINED;
195 }
196 #endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */
197
198 /* Init crypto library */
199 if (xmlSecCryptoAppInit(NULL) < 0) {
200 message(G_LOG_LEVEL_CRITICAL, "Crypto initialization failed.");
201 return LASSO_ERROR_UNDEFINED;
202 }
203
204 /* Init xmlsec-crypto library */
205 if (xmlSecCryptoInit() < 0) {
206 message(G_LOG_LEVEL_CRITICAL, "xmlsec-crypto initialization failed.");
207 return LASSO_ERROR_UNDEFINED;
208 }
209 lasso_flag_parse_environment_variable();
210 xmlSetStructuredErrorFunc(NULL, lasso_xml_structured_error_func);
211 xmlSecErrorsSetCallback(lasso_xmlsec_errors_callback);
212 return 0;
213 }
214
215 /**
216 * lasso_shutdown:
217 *
218 * Clean ups Lasso library.
219 *
220 * Return value: 0 on success; or a negative value otherwise.
221 **/
lasso_shutdown()222 int lasso_shutdown()
223 {
224 /* Shutdown xmlsec-crypto library */
225 xmlSecCryptoShutdown();
226
227 /* Shutdown crypto library */
228 xmlSecCryptoAppShutdown();
229
230 /* Shutdown xmlsec library */
231 xmlSecShutdown();
232
233 /* Shutdown libxslt/libxml */
234 #ifndef XMLSEC_NO_XSLT
235 xsltCleanupGlobals();
236 #endif /* XMLSEC_NO_XSLT */
237 /* Cleanup function for the XML library */
238 xmlCleanupParser();
239
240 /* Disallocate default registry */
241 lasso_registry_default_shutdown();
242
243 if (lasso_flag_memory_debug == TRUE) {
244 /* this is to debug memory for regression tests */
245 xmlMemoryDump();
246 }
247 return 0;
248 }
249
250 /**
251 * lasso_check_version:
252 * @major: major version numbe
253 * @minor: minor version number
254 * @subminor: subminor version number
255 * @mode: version check mode
256 *
257 * Checks if the loaded version of Lasso library could be used.
258 *
259 * Return value: 1 if the loaded lasso library version is OK to use
260 * 0 if it is not; or a negative value if an error occurs.
261 **/
262 int
lasso_check_version(int major,int minor,int subminor,LassoCheckVersionMode mode)263 lasso_check_version(int major, int minor, int subminor, LassoCheckVersionMode mode)
264 {
265 if (mode == LASSO_CHECK_VERSION_NUMERIC) {
266 if (LASSO_VERSION_MAJOR*10000 + LASSO_VERSION_MINOR*100 + LASSO_VERSION_SUBMINOR <
267 major*10000 + minor*100 + subminor)
268 return 0;
269 return 1;
270 }
271 /* we always want to have a match for major version number */
272 if (major != LASSO_VERSION_MAJOR) {
273 return 0;
274 }
275
276 if (mode == LASSO_CHECK_VERSION_EXACT) {
277 if (minor != LASSO_VERSION_MINOR || subminor != LASSO_VERSION_SUBMINOR) {
278 return 0;
279 }
280 }
281
282 if (mode == LASSO_CHECK_VERSIONABI_COMPATIBLE) {
283 if (minor < LASSO_VERSION_MINOR || (minor == LASSO_VERSION_MINOR &&
284 subminor < LASSO_VERSION_SUBMINOR)) {
285 return 0;
286 }
287 }
288
289 if (mode > LASSO_CHECK_VERSION_NUMERIC)
290 return LASSO_ERROR_UNDEFINED;
291
292 return 1;
293 }
294
295 /**
296 * lasso_set_flag:
297 * @flag: a string representing a flag name, prefix with 'no-' to disable it.
298 *
299 * Set a debugging flag. You can also use the environment variable LASSO_FLAG
300 * to get the same effect. LASSO_FLAG must contain flag name separated by spaces, commas,
301 * tabulations or colons.
302 */
lasso_set_flag(char * flag)303 void lasso_set_flag(char *flag) {
304 gboolean value = TRUE;
305
306 g_return_if_fail(flag);
307
308 /* Handle negative flags */
309 if (flag && strncmp(flag, "no-", 3) == 0) {
310 value = FALSE;
311 flag += 3;
312 }
313
314 do {
315 if (lasso_strisequal(flag,"verify-signature")) {
316 lasso_flag_verify_signature = value;
317 continue;
318 }
319 if (lasso_strisequal(flag,"memory-debug")) {
320 lasso_flag_memory_debug = value;
321 continue;
322 }
323 if (lasso_strisequal(flag,"strict-checking")) {
324 lasso_flag_strict_checking = value;
325 continue;
326 }
327 if (lasso_strisequal(flag,"add-signature")) {
328 lasso_flag_add_signature = value;
329 continue;
330 }
331 if (lasso_strisequal(flag,"sign-messages")) {
332 lasso_flag_sign_messages = value;
333 continue;
334 }
335 if (lasso_strisequal(flag,"thin-sessions")) {
336 lasso_flag_thin_sessions = value;
337 }
338 if (lasso_strisequal(flag,"pem-public-key")) {
339 lasso_flag_pem_public_key = value;
340 }
341 } while (FALSE);
342 }
343
lasso_flag_parse_environment_variable()344 static void lasso_flag_parse_environment_variable() {
345 char *lasso_flag = getenv(LASSO_FLAG_ENV_VAR);
346 char *save_ptr;
347 char *token;
348 const char delim[] = ", \t:";
349
350 if (lasso_flag) {
351 token = strtok_r(lasso_flag, delim, &save_ptr);
352 do {
353 lasso_set_flag(token);
354 } while ((token = strtok_r(NULL, delim, &save_ptr)) != NULL);
355 }
356 }
357