nm: omit deprecated g_type_init() when using >= GLIB 2.36
[strongswan.git] / src / charon-nm / nm / nm_backend.c
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * Copyright (C) 2008-2009 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "nm_service.h"
18 #include "nm_creds.h"
19 #include "nm_handler.h"
20
21 #include <hydra.h>
22 #include <daemon.h>
23 #include <processing/jobs/callback_job.h>
24
25 #ifndef CAP_DAC_OVERRIDE
26 #define CAP_DAC_OVERRIDE 1
27 #endif
28
29 typedef struct nm_backend_t nm_backend_t;
30
31 /**
32 * Data for the NetworkManager backend.
33 */
34 struct nm_backend_t {
35
36 /**
37 * NetworkManager service (VPNPlugin)
38 */
39 NMStrongswanPlugin *plugin;
40
41 /**
42 * Glib main loop for a thread, handles DBUS calls
43 */
44 GMainLoop *loop;
45
46 /**
47 * credential set registered at the daemon
48 */
49 nm_creds_t *creds;
50
51 /**
52 * attribute handler regeisterd at the daemon
53 */
54 nm_handler_t *handler;
55 };
56
57 /**
58 * Global (but private) instance of the NM backend.
59 */
60 static nm_backend_t *nm_backend = NULL;
61
62 /**
63 * NM plugin processing routine, creates and handles NMVPNPlugin
64 */
65 static job_requeue_t run(nm_backend_t *this)
66 {
67 this->loop = g_main_loop_new(NULL, FALSE);
68 g_main_loop_run(this->loop);
69 return JOB_REQUEUE_NONE;
70 }
71
72 /**
73 * Cancel the GLib Main Event Loop
74 */
75 static bool cancel(nm_backend_t *this)
76 {
77 if (this->loop)
78 {
79 if (g_main_loop_is_running(this->loop))
80 {
81 g_main_loop_quit(this->loop);
82 }
83 g_main_loop_unref(this->loop);
84 }
85 return TRUE;
86 }
87
88 /**
89 * Deinitialize NetworkManager backend
90 */
91 static void nm_backend_deinit()
92 {
93 nm_backend_t *this = nm_backend;
94
95 if (!this)
96 {
97 return;
98 }
99 if (this->plugin)
100 {
101 g_object_unref(this->plugin);
102 }
103 lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
104 hydra->attributes->remove_handler(hydra->attributes, &this->handler->handler);
105 this->creds->destroy(this->creds);
106 this->handler->destroy(this->handler);
107 free(this);
108
109 nm_backend = NULL;
110 }
111
112 /**
113 * Initialize NetworkManager backend
114 */
115 static bool nm_backend_init()
116 {
117 nm_backend_t *this;
118
119 #if !GLIB_CHECK_VERSION(2,36,0)
120 g_type_init ();
121 #endif
122
123 #if !GLIB_CHECK_VERSION(2,23,0)
124 if (!g_thread_supported())
125 {
126 g_thread_init(NULL);
127 }
128 #endif
129
130 INIT(this,
131 .creds = nm_creds_create(),
132 .handler = nm_handler_create(),
133 );
134 this->plugin = nm_strongswan_plugin_new(this->creds, this->handler);
135 nm_backend = this;
136
137 hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
138 lib->credmgr->add_set(lib->credmgr, &this->creds->set);
139 if (!this->plugin)
140 {
141 DBG1(DBG_CFG, "DBUS binding failed");
142 nm_backend_deinit();
143 return FALSE;
144 }
145
146 /* bypass file permissions to read from users ssh-agent */
147 if (!lib->caps->keep(lib->caps, CAP_DAC_OVERRIDE))
148 {
149 DBG1(DBG_CFG, "NM backend requires CAP_DAC_OVERRIDE capability");
150 nm_backend_deinit();
151 return FALSE;
152 }
153
154 lib->processor->queue_job(lib->processor,
155 (job_t*)callback_job_create_with_prio((callback_job_cb_t)run, this,
156 NULL, (callback_job_cancel_t)cancel, JOB_PRIO_CRITICAL));
157 return TRUE;
158 }
159
160 /**
161 * Initialize/deinitialize NetworkManager backend
162 */
163 static bool nm_backend_cb(void *plugin,
164 plugin_feature_t *feature, bool reg, void *data)
165 {
166 if (reg)
167 {
168 return nm_backend_init();
169 }
170 nm_backend_deinit();
171 return TRUE;
172 }
173
174 /*
175 * see header file
176 */
177 void nm_backend_register()
178 {
179 static plugin_feature_t features[] = {
180 PLUGIN_CALLBACK((plugin_feature_callback_t)nm_backend_cb, NULL),
181 PLUGIN_PROVIDE(CUSTOM, "NetworkManager backend"),
182 PLUGIN_DEPENDS(CUSTOM, "libcharon"),
183 PLUGIN_SDEPEND(PRIVKEY, KEY_RSA),
184 PLUGIN_SDEPEND(PRIVKEY, KEY_ECDSA),
185 PLUGIN_SDEPEND(CERT_DECODE, CERT_ANY),
186 PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
187 };
188 lib->plugins->add_static_features(lib->plugins, "nm-backend", features,
189 countof(features), TRUE);
190 }