git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@591 e7ae566f-a301-0410-adde-c780ea21d3b5
james authored on 2005/10/04 20:51:44... | ... |
@@ -2119,16 +2119,25 @@ do_signal_on_tls_errors (struct context *c) |
2119 | 2119 |
#ifdef ENABLE_PLUGIN |
2120 | 2120 |
|
2121 | 2121 |
void |
2122 |
-open_plugins (struct context *c, const bool import_options) |
|
2122 |
+init_plugins (struct context *c) |
|
2123 | 2123 |
{ |
2124 | 2124 |
if (c->options.plugin_list && !c->plugins) |
2125 | 2125 |
{ |
2126 |
+ c->plugins = plugin_list_init (c->options.plugin_list); |
|
2127 |
+ c->plugins_owned = true; |
|
2128 |
+ } |
|
2129 |
+} |
|
2130 |
+ |
|
2131 |
+void |
|
2132 |
+open_plugins (struct context *c, const bool import_options, int init_point) |
|
2133 |
+{ |
|
2134 |
+ if (c->plugins && c->plugins_owned) |
|
2135 |
+ { |
|
2126 | 2136 |
if (import_options) |
2127 | 2137 |
{ |
2128 | 2138 |
struct plugin_return pr, config; |
2129 | 2139 |
plugin_return_init (&pr); |
2130 |
- c->plugins = plugin_list_open (c->options.plugin_list, &pr, c->c2.es); |
|
2131 |
- c->plugins_owned = true; |
|
2140 |
+ plugin_list_open (c->plugins, c->options.plugin_list, &pr, c->c2.es, init_point); |
|
2132 | 2141 |
plugin_return_get_column (&pr, &config, "config"); |
2133 | 2142 |
if (plugin_return_defined (&config)) |
2134 | 2143 |
{ |
... | ... |
@@ -2149,8 +2158,7 @@ open_plugins (struct context *c, const bool import_options) |
2149 | 2149 |
} |
2150 | 2150 |
else |
2151 | 2151 |
{ |
2152 |
- c->plugins = plugin_list_open (c->options.plugin_list, NULL, c->c2.es); |
|
2153 |
- c->plugins_owned = true; |
|
2152 |
+ plugin_list_open (c->plugins, c->options.plugin_list, NULL, c->c2.es, init_point); |
|
2154 | 2153 |
} |
2155 | 2154 |
} |
2156 | 2155 |
} |
... | ... |
@@ -2360,7 +2368,7 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int |
2360 | 2360 |
#ifdef ENABLE_PLUGIN |
2361 | 2361 |
/* initialize plugins */ |
2362 | 2362 |
if (c->mode == CM_P2P || c->mode == CM_TOP) |
2363 |
- open_plugins (c, false); |
|
2363 |
+ open_plugins (c, false, OPENVPN_PLUGIN_INIT_PRE_DAEMON); |
|
2364 | 2364 |
#endif |
2365 | 2365 |
|
2366 | 2366 |
/* should we enable fast I/O? */ |
... | ... |
@@ -2464,6 +2472,12 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int |
2464 | 2464 |
/* do one-time inits, and possibily become a daemon here */ |
2465 | 2465 |
do_init_first_time (c); |
2466 | 2466 |
|
2467 |
+#ifdef ENABLE_PLUGIN |
|
2468 |
+ /* initialize plugins */ |
|
2469 |
+ if (c->mode == CM_P2P || c->mode == CM_TOP) |
|
2470 |
+ open_plugins (c, false, OPENVPN_PLUGIN_INIT_POST_DAEMON); |
|
2471 |
+#endif |
|
2472 |
+ |
|
2467 | 2473 |
/* |
2468 | 2474 |
* Actually do UID/GID downgrade, and chroot, if requested. |
2469 | 2475 |
* May be delayed by --client, --pull, or --up-delay. |
... | ... |
@@ -2478,6 +2492,12 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int |
2478 | 2478 |
if (c->mode == CM_P2P || child) |
2479 | 2479 |
do_init_timers (c, false); |
2480 | 2480 |
|
2481 |
+#ifdef ENABLE_PLUGIN |
|
2482 |
+ /* initialize plugins */ |
|
2483 |
+ if (c->mode == CM_P2P || c->mode == CM_TOP) |
|
2484 |
+ open_plugins (c, false, OPENVPN_PLUGIN_INIT_POST_UID_CHANGE); |
|
2485 |
+#endif |
|
2486 |
+ |
|
2481 | 2487 |
/* Check for signals */ |
2482 | 2488 |
if (IS_SIG (c)) |
2483 | 2489 |
goto sig; |
... | ... |
@@ -118,7 +118,8 @@ void init_management_callback_p2p (struct context *c); |
118 | 118 |
void uninit_management_callback (void); |
119 | 119 |
|
120 | 120 |
#ifdef ENABLE_PLUGIN |
121 |
-void open_plugins (struct context *c, const bool import_options); |
|
121 |
+void init_plugins (struct context *c); |
|
122 |
+void open_plugins (struct context *c, const bool import_options, int init_point); |
|
122 | 123 |
#endif |
123 | 124 |
|
124 | 125 |
#endif |
... | ... |
@@ -290,6 +290,30 @@ OPENVPN_PLUGIN_DEF void OPENVPN_PLUGIN_FUNC(openvpn_plugin_client_destructor_v1) |
290 | 290 |
(openvpn_plugin_handle_t handle, void *per_client_context); |
291 | 291 |
|
292 | 292 |
/* |
293 |
+ * FUNCTION: openvpn_plugin_select_initialization_point_v1 |
|
294 |
+ * |
|
295 |
+ * Several different points exist in OpenVPN's initialization sequence where |
|
296 |
+ * the openvpn_plugin_open function can be called. While the default is |
|
297 |
+ * OPENVPN_PLUGIN_INIT_PRE_DAEMON, this function can be used to select a |
|
298 |
+ * different initialization point. For example, if your plugin needs to |
|
299 |
+ * return configuration parameters to OpenVPN, use |
|
300 |
+ * OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE. |
|
301 |
+ * |
|
302 |
+ * REQUIRED: NO |
|
303 |
+ * |
|
304 |
+ * RETURN VALUE: |
|
305 |
+ * |
|
306 |
+ * An OPENVPN_PLUGIN_INIT_x value. |
|
307 |
+ */ |
|
308 |
+#define OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE 1 |
|
309 |
+#define OPENVPN_PLUGIN_INIT_PRE_DAEMON 2 /* default */ |
|
310 |
+#define OPENVPN_PLUGIN_INIT_POST_DAEMON 3 |
|
311 |
+#define OPENVPN_PLUGIN_INIT_POST_UID_CHANGE 4 |
|
312 |
+ |
|
313 |
+OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_select_initialization_point_v1) |
|
314 |
+ (void); |
|
315 |
+ |
|
316 |
+/* |
|
293 | 317 |
* FUNCTION: openvpn_plugin_min_version_required_v1 |
294 | 318 |
* |
295 | 319 |
* This function is called by OpenVPN to query the minimum |
... | ... |
@@ -149,7 +149,8 @@ main (int argc, char *argv[]) |
149 | 149 |
#ifdef ENABLE_PLUGIN |
150 | 150 |
/* plugins may contribute options configuration */ |
151 | 151 |
init_verb_mute (&c, IVM_LEVEL_1); |
152 |
- open_plugins (&c, true); |
|
152 |
+ init_plugins (&c); |
|
153 |
+ open_plugins (&c, true, OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE); |
|
153 | 154 |
#endif |
154 | 155 |
|
155 | 156 |
/* init verbosity and mute levels */ |
... | ... |
@@ -176,13 +176,9 @@ dll_resolve_symbol (HMODULE module, void **dest, const char *symbol, const char |
176 | 176 |
#endif |
177 | 177 |
|
178 | 178 |
static void |
179 |
-plugin_init_item (struct plugin *p, |
|
180 |
- const struct plugin_option *o, |
|
181 |
- struct openvpn_plugin_string_list **retlist, |
|
182 |
- const char **envp) |
|
179 |
+plugin_init_item (struct plugin *p, const struct plugin_option *o) |
|
183 | 180 |
{ |
184 | 181 |
struct gc_arena gc = gc_new (); |
185 |
- const char **argv = make_arg_array (o->so_pathname, o->args, &gc); |
|
186 | 182 |
p->so_pathname = o->so_pathname; |
187 | 183 |
p->plugin_type_mask = plugin_supported_types (); |
188 | 184 |
|
... | ... |
@@ -210,9 +206,10 @@ plugin_init_item (struct plugin *p, |
210 | 210 |
PLUGIN_SYM (func2, "openvpn_plugin_func_v2", 0); |
211 | 211 |
PLUGIN_SYM (close, "openvpn_plugin_close_v1", PLUGIN_SYMBOL_REQUIRED); |
212 | 212 |
PLUGIN_SYM (abort, "openvpn_plugin_abort_v1", 0); |
213 |
- PLUGIN_SYM (min_version_required, "openvpn_plugin_min_version_required_v1", 0); |
|
214 | 213 |
PLUGIN_SYM (client_constructor, "openvpn_plugin_client_constructor_v1", 0); |
215 | 214 |
PLUGIN_SYM (client_destructor, "openvpn_plugin_client_destructor_v1", 0); |
215 |
+ PLUGIN_SYM (min_version_required, "openvpn_plugin_min_version_required_v1", 0); |
|
216 |
+ PLUGIN_SYM (initialization_point, "openvpn_plugin_select_initialization_point_v1", 0); |
|
216 | 217 |
|
217 | 218 |
if (!p->open1 && !p->open2) |
218 | 219 |
msg (M_FATAL, "PLUGIN: symbol openvpn_plugin_open_vX is undefined in plugin: %s", p->so_pathname); |
... | ... |
@@ -220,9 +217,6 @@ plugin_init_item (struct plugin *p, |
220 | 220 |
if (!p->func1 && !p->func2) |
221 | 221 |
msg (M_FATAL, "PLUGIN: symbol openvpn_plugin_func_vX is undefined in plugin: %s", p->so_pathname); |
222 | 222 |
|
223 |
- dmsg (D_PLUGIN_DEBUG, "PLUGIN_INIT: PRE"); |
|
224 |
- plugin_show_args_env (D_PLUGIN_DEBUG, argv, envp); |
|
225 |
- |
|
226 | 223 |
/* |
227 | 224 |
* Verify that we are sufficiently up-to-date to handle the plugin |
228 | 225 |
*/ |
... | ... |
@@ -236,36 +230,65 @@ plugin_init_item (struct plugin *p, |
236 | 236 |
p->so_pathname); |
237 | 237 |
} |
238 | 238 |
|
239 |
+ if (p->initialization_point) |
|
240 |
+ p->requested_initialization_point = (*p->initialization_point)(); |
|
241 |
+ else |
|
242 |
+ p->requested_initialization_point = OPENVPN_PLUGIN_INIT_PRE_DAEMON; |
|
243 |
+ |
|
244 |
+ p->initialized = true; |
|
245 |
+ |
|
246 |
+ gc_free (&gc); |
|
247 |
+} |
|
248 |
+ |
|
249 |
+static void |
|
250 |
+plugin_open_item (struct plugin *p, |
|
251 |
+ const struct plugin_option *o, |
|
252 |
+ struct openvpn_plugin_string_list **retlist, |
|
253 |
+ const char **envp, |
|
254 |
+ const int init_point) |
|
255 |
+{ |
|
256 |
+ ASSERT (p->initialized); |
|
257 |
+ |
|
258 |
+ /* clear return list */ |
|
239 | 259 |
if (retlist) |
240 | 260 |
*retlist = NULL; |
241 | 261 |
|
242 |
- /* |
|
243 |
- * Call the plugin initialization |
|
244 |
- */ |
|
245 |
- if (p->open2) |
|
246 |
- p->plugin_handle = (*p->open2)(&p->plugin_type_mask, argv, envp, retlist); |
|
247 |
- else if (p->open1) |
|
248 |
- p->plugin_handle = (*p->open1)(&p->plugin_type_mask, argv, envp); |
|
249 |
- else |
|
250 |
- ASSERT (0); |
|
262 |
+ if (!p->plugin_handle && init_point == p->requested_initialization_point) |
|
263 |
+ { |
|
264 |
+ struct gc_arena gc = gc_new (); |
|
265 |
+ const char **argv = make_arg_array (o->so_pathname, o->args, &gc); |
|
251 | 266 |
|
252 |
- msg (D_PLUGIN, "PLUGIN_INIT: POST %s '%s' intercepted=%s %s", |
|
253 |
- p->so_pathname, |
|
254 |
- o->args ? o->args : "[NULL]", |
|
255 |
- plugin_mask_string (p->plugin_type_mask, &gc), |
|
256 |
- (retlist && *retlist) ? "[RETLIST]" : ""); |
|
267 |
+ dmsg (D_PLUGIN_DEBUG, "PLUGIN_INIT: PRE"); |
|
268 |
+ plugin_show_args_env (D_PLUGIN_DEBUG, argv, envp); |
|
257 | 269 |
|
258 |
- if ((p->plugin_type_mask | plugin_supported_types()) != plugin_supported_types()) |
|
259 |
- msg (M_FATAL, "PLUGIN_INIT: plugin %s expressed interest in unsupported plugin types: [want=0x%08x, have=0x%08x]", |
|
260 |
- p->so_pathname, |
|
261 |
- p->plugin_type_mask, |
|
262 |
- plugin_supported_types()); |
|
270 |
+ /* |
|
271 |
+ * Call the plugin initialization |
|
272 |
+ */ |
|
273 |
+ if (p->open2) |
|
274 |
+ p->plugin_handle = (*p->open2)(&p->plugin_type_mask, argv, envp, retlist); |
|
275 |
+ else if (p->open1) |
|
276 |
+ p->plugin_handle = (*p->open1)(&p->plugin_type_mask, argv, envp); |
|
277 |
+ else |
|
278 |
+ ASSERT (0); |
|
263 | 279 |
|
264 |
- if (p->plugin_handle == NULL) |
|
265 |
- msg (M_FATAL, "PLUGIN_INIT: plugin initialization function failed: %s", |
|
266 |
- p->so_pathname); |
|
280 |
+ msg (D_PLUGIN, "PLUGIN_INIT: POST %s '%s' intercepted=%s %s", |
|
281 |
+ p->so_pathname, |
|
282 |
+ o->args ? o->args : "[NULL]", |
|
283 |
+ plugin_mask_string (p->plugin_type_mask, &gc), |
|
284 |
+ (retlist && *retlist) ? "[RETLIST]" : ""); |
|
285 |
+ |
|
286 |
+ if ((p->plugin_type_mask | plugin_supported_types()) != plugin_supported_types()) |
|
287 |
+ msg (M_FATAL, "PLUGIN_INIT: plugin %s expressed interest in unsupported plugin types: [want=0x%08x, have=0x%08x]", |
|
288 |
+ p->so_pathname, |
|
289 |
+ p->plugin_type_mask, |
|
290 |
+ plugin_supported_types()); |
|
291 |
+ |
|
292 |
+ if (p->plugin_handle == NULL) |
|
293 |
+ msg (M_FATAL, "PLUGIN_INIT: plugin initialization function failed: %s", |
|
294 |
+ p->so_pathname); |
|
267 | 295 |
|
268 |
- gc_free (&gc); |
|
296 |
+ gc_free (&gc); |
|
297 |
+ } |
|
269 | 298 |
} |
270 | 299 |
|
271 | 300 |
static int |
... | ... |
@@ -278,7 +301,11 @@ plugin_call_item (const struct plugin *p, |
278 | 278 |
{ |
279 | 279 |
int status = OPENVPN_PLUGIN_FUNC_SUCCESS; |
280 | 280 |
|
281 |
- if (p->plugin_type_mask & OPENVPN_PLUGIN_MASK (type)) |
|
281 |
+ /* clear return list */ |
|
282 |
+ if (retlist) |
|
283 |
+ *retlist = NULL; |
|
284 |
+ |
|
285 |
+ if (p->plugin_handle && (p->plugin_type_mask & OPENVPN_PLUGIN_MASK (type))) |
|
282 | 286 |
{ |
283 | 287 |
struct gc_arena gc = gc_new (); |
284 | 288 |
const char **argv = make_arg_array (p->so_pathname, args, &gc); |
... | ... |
@@ -286,9 +313,6 @@ plugin_call_item (const struct plugin *p, |
286 | 286 |
dmsg (D_PLUGIN_DEBUG, "PLUGIN_CALL: PRE type=%s", plugin_type_name (type)); |
287 | 287 |
plugin_show_args_env (D_PLUGIN_DEBUG, argv, envp); |
288 | 288 |
|
289 |
- if (retlist) |
|
290 |
- *retlist = NULL; |
|
291 |
- |
|
292 | 289 |
/* |
293 | 290 |
* Call the plugin work function |
294 | 291 |
*/ |
... | ... |
@@ -316,22 +340,28 @@ plugin_call_item (const struct plugin *p, |
316 | 316 |
} |
317 | 317 |
|
318 | 318 |
static void |
319 |
-plugin_close_item (const struct plugin *p) |
|
319 |
+plugin_close_item (struct plugin *p) |
|
320 | 320 |
{ |
321 |
- msg (D_PLUGIN, "PLUGIN_CLOSE: %s", p->so_pathname); |
|
321 |
+ if (p->initialized) |
|
322 |
+ { |
|
323 |
+ msg (D_PLUGIN, "PLUGIN_CLOSE: %s", p->so_pathname); |
|
322 | 324 |
|
323 |
- /* |
|
324 |
- * Call the plugin close function |
|
325 |
- */ |
|
326 |
- (*p->close)(p->plugin_handle); |
|
325 |
+ /* |
|
326 |
+ * Call the plugin close function |
|
327 |
+ */ |
|
328 |
+ if (p->plugin_handle) |
|
329 |
+ (*p->close)(p->plugin_handle); |
|
327 | 330 |
|
328 | 331 |
#if defined(USE_LIBDL) |
329 |
- if (dlclose (p->handle)) |
|
330 |
- msg (M_WARN, "PLUGIN_CLOSE: dlclose() failed on plugin: %s", p->so_pathname); |
|
332 |
+ if (dlclose (p->handle)) |
|
333 |
+ msg (M_WARN, "PLUGIN_CLOSE: dlclose() failed on plugin: %s", p->so_pathname); |
|
331 | 334 |
#elif defined(USE_LOAD_LIBRARY) |
332 |
- if (!FreeLibrary (p->module)) |
|
333 |
- msg (M_WARN, "PLUGIN_CLOSE: FreeLibrary() failed on plugin: %s", p->so_pathname); |
|
335 |
+ if (!FreeLibrary (p->module)) |
|
336 |
+ msg (M_WARN, "PLUGIN_CLOSE: FreeLibrary() failed on plugin: %s", p->so_pathname); |
|
334 | 337 |
#endif |
338 |
+ |
|
339 |
+ p->initialized = false; |
|
340 |
+ } |
|
335 | 341 |
} |
336 | 342 |
|
337 | 343 |
static void |
... | ... |
@@ -345,7 +375,9 @@ plugin_abort_item (const struct plugin *p) |
345 | 345 |
} |
346 | 346 |
|
347 | 347 |
static void |
348 |
-plugin_per_client_init (const struct plugin_common *pc, struct plugin_per_client *cli) |
|
348 |
+plugin_per_client_init (const struct plugin_common *pc, |
|
349 |
+ struct plugin_per_client *cli, |
|
350 |
+ const int init_point) |
|
349 | 351 |
{ |
350 | 352 |
const int n = pc->n; |
351 | 353 |
int i; |
... | ... |
@@ -354,31 +386,28 @@ plugin_per_client_init (const struct plugin_common *pc, struct plugin_per_client |
354 | 354 |
for (i = 0; i < n; ++i) |
355 | 355 |
{ |
356 | 356 |
const struct plugin *p = &pc->plugins[i]; |
357 |
- |
|
358 |
- if (p->client_constructor) |
|
357 |
+ if (p->plugin_handle |
|
358 |
+ && (init_point < 0 || init_point == p->requested_initialization_point) |
|
359 |
+ && p->client_constructor) |
|
359 | 360 |
cli->per_client_context[i] = (*p->client_constructor)(p->plugin_handle); |
360 | 361 |
} |
361 |
- cli->initialized = true; |
|
362 | 362 |
} |
363 | 363 |
|
364 | 364 |
static void |
365 | 365 |
plugin_per_client_destroy (const struct plugin_common *pc, struct plugin_per_client *cli) |
366 | 366 |
{ |
367 |
- if (cli->initialized) |
|
368 |
- { |
|
369 |
- const int n = pc->n; |
|
370 |
- int i; |
|
367 |
+ const int n = pc->n; |
|
368 |
+ int i; |
|
371 | 369 |
|
372 |
- for (i = 0; i < n; ++i) |
|
373 |
- { |
|
374 |
- const struct plugin *p = &pc->plugins[i]; |
|
375 |
- void *cc = cli->per_client_context[i]; |
|
370 |
+ for (i = 0; i < n; ++i) |
|
371 |
+ { |
|
372 |
+ const struct plugin *p = &pc->plugins[i]; |
|
373 |
+ void *cc = cli->per_client_context[i]; |
|
376 | 374 |
|
377 |
- if (p->client_destructor && cc) |
|
378 |
- (*p->client_destructor)(p->plugin_handle, cc); |
|
379 |
- } |
|
380 |
- CLEAR (*cli); |
|
375 |
+ if (p->client_destructor && cc) |
|
376 |
+ (*p->client_destructor)(p->plugin_handle, cc); |
|
381 | 377 |
} |
378 |
+ CLEAR (*cli); |
|
382 | 379 |
} |
383 | 380 |
|
384 | 381 |
struct plugin_list * |
... | ... |
@@ -388,42 +417,58 @@ plugin_list_inherit (const struct plugin_list *src) |
388 | 388 |
ALLOC_OBJ_CLEAR (pl, struct plugin_list); |
389 | 389 |
pl->common = src->common; |
390 | 390 |
ASSERT (pl->common); |
391 |
- plugin_per_client_init (pl->common, &pl->per_client); |
|
391 |
+ plugin_per_client_init (pl->common, &pl->per_client, -1); |
|
392 | 392 |
return pl; |
393 | 393 |
} |
394 | 394 |
|
395 | 395 |
static struct plugin_common * |
396 |
-plugin_common_open (const struct plugin_option_list *list, |
|
397 |
- struct plugin_return *pr, |
|
398 |
- const struct env_set *es) |
|
396 |
+plugin_common_init (const struct plugin_option_list *list) |
|
399 | 397 |
{ |
400 |
- struct gc_arena gc = gc_new (); |
|
401 | 398 |
int i; |
402 | 399 |
struct plugin_common *pc; |
403 |
- const char **envp; |
|
404 | 400 |
|
405 | 401 |
ALLOC_OBJ_CLEAR (pc, struct plugin_common); |
406 | 402 |
|
403 |
+ for (i = 0; i < list->n; ++i) |
|
404 |
+ { |
|
405 |
+ plugin_init_item (&pc->plugins[i], |
|
406 |
+ &list->plugins[i]); |
|
407 |
+ pc->n = i + 1; |
|
408 |
+ } |
|
409 |
+ |
|
410 |
+ static_plugin_common = pc; |
|
411 |
+ return pc; |
|
412 |
+} |
|
413 |
+ |
|
414 |
+static void |
|
415 |
+plugin_common_open (struct plugin_common *pc, |
|
416 |
+ const struct plugin_option_list *list, |
|
417 |
+ struct plugin_return *pr, |
|
418 |
+ const struct env_set *es, |
|
419 |
+ const int init_point) |
|
420 |
+{ |
|
421 |
+ struct gc_arena gc = gc_new (); |
|
422 |
+ int i; |
|
423 |
+ const char **envp; |
|
424 |
+ |
|
407 | 425 |
envp = make_env_array (es, &gc); |
408 | 426 |
|
409 | 427 |
if (pr) |
410 | 428 |
plugin_return_init (pr); |
411 | 429 |
|
412 |
- for (i = 0; i < list->n; ++i) |
|
430 |
+ for (i = 0; i < pc->n; ++i) |
|
413 | 431 |
{ |
414 |
- plugin_init_item (&pc->plugins[i], |
|
432 |
+ plugin_open_item (&pc->plugins[i], |
|
415 | 433 |
&list->plugins[i], |
416 | 434 |
pr ? &pr->list[i] : NULL, |
417 |
- envp); |
|
418 |
- pc->n = i + 1; |
|
435 |
+ envp, |
|
436 |
+ init_point); |
|
419 | 437 |
} |
420 | 438 |
|
421 | 439 |
if (pr) |
422 | 440 |
pr->n = i; |
423 | 441 |
|
424 | 442 |
gc_free (&gc); |
425 |
- static_plugin_common = pc; |
|
426 |
- return pc; |
|
427 | 443 |
} |
428 | 444 |
|
429 | 445 |
static void |
... | ... |
@@ -441,18 +486,26 @@ plugin_common_close (struct plugin_common *pc) |
441 | 441 |
} |
442 | 442 |
|
443 | 443 |
struct plugin_list * |
444 |
-plugin_list_open (const struct plugin_option_list *list, |
|
445 |
- struct plugin_return *pr, |
|
446 |
- const struct env_set *es) |
|
444 |
+plugin_list_init (const struct plugin_option_list *list) |
|
447 | 445 |
{ |
448 | 446 |
struct plugin_list *pl; |
449 | 447 |
ALLOC_OBJ_CLEAR (pl, struct plugin_list); |
450 |
- pl->common = plugin_common_open (list, pr, es); |
|
448 |
+ pl->common = plugin_common_init (list); |
|
451 | 449 |
pl->common_owned = true; |
452 |
- plugin_per_client_init (pl->common, &pl->per_client); |
|
453 | 450 |
return pl; |
454 | 451 |
} |
455 | 452 |
|
453 |
+void |
|
454 |
+plugin_list_open (struct plugin_list *pl, |
|
455 |
+ const struct plugin_option_list *list, |
|
456 |
+ struct plugin_return *pr, |
|
457 |
+ const struct env_set *es, |
|
458 |
+ const int init_point) |
|
459 |
+{ |
|
460 |
+ plugin_common_open (pl->common, list, pr, es, init_point); |
|
461 |
+ plugin_per_client_init (pl->common, &pl->per_client, init_point); |
|
462 |
+} |
|
463 |
+ |
|
456 | 464 |
int |
457 | 465 |
plugin_call (const struct plugin_list *pl, |
458 | 466 |
const int type, |
... | ... |
@@ -479,8 +532,7 @@ plugin_call (const struct plugin_list *pl, |
479 | 479 |
for (i = 0; i < n; ++i) |
480 | 480 |
{ |
481 | 481 |
if (!plugin_call_item (&pl->common->plugins[i], |
482 |
- pl->per_client.initialized |
|
483 |
- ? pl->per_client.per_client_context[i] : NULL, |
|
482 |
+ pl->per_client.per_client_context[i], |
|
484 | 483 |
type, |
485 | 484 |
args, |
486 | 485 |
pr ? &pr->list[i] : NULL, |
... | ... |
@@ -508,7 +560,6 @@ plugin_list_close (struct plugin_list *pl) |
508 | 508 |
{ |
509 | 509 |
if (pl) |
510 | 510 |
{ |
511 |
- |
|
512 | 511 |
if (pl->common) |
513 | 512 |
{ |
514 | 513 |
plugin_per_client_destroy (pl->common, &pl->per_client); |
... | ... |
@@ -48,8 +48,10 @@ struct plugin_option_list { |
48 | 48 |
}; |
49 | 49 |
|
50 | 50 |
struct plugin { |
51 |
+ bool initialized; |
|
51 | 52 |
const char *so_pathname; |
52 | 53 |
unsigned int plugin_type_mask; |
54 |
+ int requested_initialization_point; |
|
53 | 55 |
|
54 | 56 |
#if defined(USE_LIBDL) |
55 | 57 |
void *handle; |
... | ... |
@@ -63,16 +65,17 @@ struct plugin { |
63 | 63 |
openvpn_plugin_func_v2 func2; |
64 | 64 |
openvpn_plugin_close_v1 close; |
65 | 65 |
openvpn_plugin_abort_v1 abort; |
66 |
- openvpn_plugin_min_version_required_v1 min_version_required; |
|
67 | 66 |
openvpn_plugin_client_constructor_v1 client_constructor; |
68 | 67 |
openvpn_plugin_client_destructor_v1 client_destructor; |
68 |
+ openvpn_plugin_min_version_required_v1 min_version_required; |
|
69 |
+ openvpn_plugin_select_initialization_point_v1 initialization_point; |
|
69 | 70 |
|
70 | 71 |
openvpn_plugin_handle_t plugin_handle; |
71 | 72 |
}; |
72 | 73 |
|
73 | 74 |
struct plugin_per_client |
74 | 75 |
{ |
75 |
- bool initialized; |
|
76 |
+ //bool initialized; JYFIXME |
|
76 | 77 |
void *per_client_context[MAX_PLUGINS]; |
77 | 78 |
}; |
78 | 79 |
|
... | ... |
@@ -102,9 +105,13 @@ bool plugin_option_list_add (struct plugin_option_list *list, const char *so_pat |
102 | 102 |
void plugin_option_list_print (const struct plugin_option_list *list, int msglevel); |
103 | 103 |
#endif |
104 | 104 |
|
105 |
-struct plugin_list *plugin_list_open (const struct plugin_option_list *list, |
|
106 |
- struct plugin_return *pr, |
|
107 |
- const struct env_set *es); |
|
105 |
+struct plugin_list *plugin_list_init (const struct plugin_option_list *list); |
|
106 |
+ |
|
107 |
+void plugin_list_open (struct plugin_list *pl, |
|
108 |
+ const struct plugin_option_list *list, |
|
109 |
+ struct plugin_return *pr, |
|
110 |
+ const struct env_set *es, |
|
111 |
+ const int init_point); |
|
108 | 112 |
|
109 | 113 |
struct plugin_list *plugin_list_inherit (const struct plugin_list *src); |
110 | 114 |
|
... | ... |
@@ -48,7 +48,7 @@ |
48 | 48 |
|
49 | 49 |
#include "openvpn-plugin.h" |
50 | 50 |
|
51 |
-#define DEBUG(verb) ((verb) >= 7) |
|
51 |
+#define DEBUG(verb) ((verb) >= 4) |
|
52 | 52 |
|
53 | 53 |
/* Command codes for foreground -> background communication */ |
54 | 54 |
#define COMMAND_VERIFY 0 |
... | ... |
@@ -206,6 +206,8 @@ send_string (int fd, const char *string) |
206 | 206 |
return -1; |
207 | 207 |
} |
208 | 208 |
|
209 |
+#ifdef DO_DAEMONIZE |
|
210 |
+ |
|
209 | 211 |
/* |
210 | 212 |
* Daemonize if "daemon" env var is true. |
211 | 213 |
* Preserve stderr across daemonization if |
... | ... |
@@ -233,6 +235,8 @@ daemonize (const char *envp[]) |
233 | 233 |
} |
234 | 234 |
} |
235 | 235 |
|
236 |
+#endif |
|
237 |
+ |
|
236 | 238 |
/* |
237 | 239 |
* Close most of parent's fds. |
238 | 240 |
* Keep stdin/stdout/stderr, plus one |
... | ... |
@@ -405,8 +409,10 @@ openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char |
405 | 405 |
/* Ignore most signals (the parent will receive them) */ |
406 | 406 |
set_signals (); |
407 | 407 |
|
408 |
+#ifdef DO_DAEMONIZE |
|
408 | 409 |
/* Daemonize if --daemon option is set. */ |
409 | 410 |
daemonize (envp); |
411 |
+#endif |
|
410 | 412 |
|
411 | 413 |
/* execute the event loop */ |
412 | 414 |
pam_server (fd[1], argv[1], context->verb, &name_value_list); |