summaryrefslogtreecommitdiffstats
path: root/openvpn-plugin.h
blob: 56b0a701574e6913b3a714e941cdc4899dbea8e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
/*
 *  OpenVPN -- An application to securely tunnel IP networks
 *             over a single TCP/UDP port, with support for SSL/TLS-based
 *             session authentication and key exchange,
 *             packet encryption, packet authentication, and
 *             packet compression.
 *
 *  Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program (see the file COPYING included with this
 *  distribution); if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#define OPENVPN_PLUGIN_VERSION 2

/*
 * Plug-in types.  These types correspond to the set of script callbacks
 * supported by OpenVPN.
 *
 * This is the general call sequence to expect when running in server mode:
 *
 * Initial Server Startup:
 *
 * FUNC: openvpn_plugin_open_v1
 * FUNC: openvpn_plugin_client_constructor_v1 (this is the top-level "generic"
 *                                             client template)
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_UP
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_ROUTE_UP
 *
 * New Client Connection:
 *
 * FUNC: openvpn_plugin_client_constructor_v1
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_TLS_VERIFY (called once for every cert
 *                                                     in the server chain)
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_TLS_FINAL
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_IPCHANGE
 *
 * [If OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY returned OPENVPN_PLUGIN_FUNC_DEFERRED,
 * we don't proceed until authentication is verified via auth_control_file]
 *
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_CLIENT_CONNECT_V2
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_LEARN_ADDRESS
 * 
 * [Client session ensues]
 *
 * For each "TLS soft reset", according to reneg-sec option (or similar):
 *
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_ENABLE_PF
 *
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_TLS_VERIFY (called once for every cert
 *                                                     in the server chain)
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_TLS_FINAL
 * 
 * [If OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY returned OPENVPN_PLUGIN_FUNC_DEFERRED,
 * we expect that authentication is verified via auth_control_file within
 * the number of seconds defined by the "hand-window" option.  Data channel traffic
 * will continue to flow uninterrupted during this period.]
 *
 * [Client session continues]
 *
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_CLIENT_DISCONNECT
 * FUNC: openvpn_plugin_client_constructor_v1
 *
 * [ some time may pass ]
 *
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_LEARN_ADDRESS (this coincides with a
 *                                                            lazy free of initial
 *                                                            learned addr object)
 * Server Shutdown:
 *
 * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_DOWN
 * FUNC: openvpn_plugin_client_destructor_v1 (top-level "generic" client)
 * FUNC: openvpn_plugin_close_v1
 */
#define OPENVPN_PLUGIN_UP                    0
#define OPENVPN_PLUGIN_DOWN                  1
#define OPENVPN_PLUGIN_ROUTE_UP              2
#define OPENVPN_PLUGIN_IPCHANGE              3
#define OPENVPN_PLUGIN_TLS_VERIFY            4
#define OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY 5
#define OPENVPN_PLUGIN_CLIENT_CONNECT        6
#define OPENVPN_PLUGIN_CLIENT_DISCONNECT     7
#define OPENVPN_PLUGIN_LEARN_ADDRESS         8
#define OPENVPN_PLUGIN_CLIENT_CONNECT_V2     9
#define OPENVPN_PLUGIN_TLS_FINAL             10
#define OPENVPN_PLUGIN_ENABLE_PF             11
#define OPENVPN_PLUGIN_N                     12

/*
 * Build a mask out of a set of plug-in types.
 */
#define OPENVPN_PLUGIN_MASK(x) (1<<(x))

/*
 * A pointer to a plugin-defined object which contains
 * the object state.
 */
typedef void *openvpn_plugin_handle_t;

/*
 * Return value for openvpn_plugin_func_v1 function
 */
#define OPENVPN_PLUGIN_FUNC_SUCCESS  0
#define OPENVPN_PLUGIN_FUNC_ERROR    1
#define OPENVPN_PLUGIN_FUNC_DEFERRED 2

/*
 * For Windows (needs to be modified for MSVC)
 */
#if defined(__MINGW32_VERSION) && !defined(OPENVPN_PLUGIN_H)
# define OPENVPN_EXPORT __declspec(dllexport)
#else
# define OPENVPN_EXPORT
#endif

/*
 * If OPENVPN_PLUGIN_H is defined, we know that we are being
 * included in an OpenVPN compile, rather than a plugin compile.
 */
#ifdef OPENVPN_PLUGIN_H

/*
 * We are compiling OpenVPN.
 */
#define OPENVPN_PLUGIN_DEF        typedef
#define OPENVPN_PLUGIN_FUNC(name) (*name)

#else

/*
 * We are compiling plugin.
 */
#define OPENVPN_PLUGIN_DEF        OPENVPN_EXPORT
#define OPENVPN_PLUGIN_FUNC(name) name

#endif

/*
 * Used by openvpn_plugin_func to return structured
 * data.  The plugin should allocate all structure
 * instances, name strings, and value strings with
 * malloc, since OpenVPN will assume that it
 * can free the list by calling free() over the same.
 */
struct openvpn_plugin_string_list
{
  struct openvpn_plugin_string_list *next;
  char *name;
  char *value;
};

/*
 * Multiple plugin modules can be cascaded, and modules can be
 * used in tandem with scripts.  The order of operation is that
 * the module func() functions are called in the order that
 * the modules were specified in the config file.  If a script
 * was specified as well, it will be called last.  If the
 * return code of the module/script controls an authentication
 * function (such as tls-verify or auth-user-pass-verify), then
 * every module and script must return success (0) in order for
 * the connection to be authenticated.
 *
 * Notes:
 *
 * Plugins which use a privilege-separation model (by forking in
 * their initialization function before the main OpenVPN process
 * downgrades root privileges and/or executes a chroot) must
 * daemonize after a fork if the "daemon" environmental variable is
 * set.  In addition, if the "daemon_log_redirect" variable is set,
 * the plugin should preserve stdout/stderr across the daemon()
 * syscall.  See the daemonize() function in plugin/auth-pam/auth-pam.c
 * for an example.
 */

/*
 * Prototypes for functions which OpenVPN plug-ins must define.
 */

/*
 * FUNCTION: openvpn_plugin_open_v2
 *
 * REQUIRED: YES
 * 
 * Called on initial plug-in load.  OpenVPN will preserve plug-in state
 * across SIGUSR1 restarts but not across SIGHUP restarts.  A SIGHUP reset
 * will cause the plugin to be closed and reopened.
 *
 * ARGUMENTS
 *
 * *type_mask : Set by OpenVPN to the logical OR of all script
 *              types which this version of OpenVPN supports.  The plug-in
 *              should set this value to the logical OR of all script types
 *              which the plug-in wants to intercept.  For example, if the
 *              script wants to intercept the client-connect and
 *              client-disconnect script types:
 *
 *              *type_mask = OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_CONNECT)
 *                         | OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_DISCONNECT)
 *
 * argv : a NULL-terminated array of options provided to the OpenVPN
 *        "plug-in" directive.  argv[0] is the dynamic library pathname.
 *
 * envp : a NULL-terminated array of OpenVPN-set environmental
 *        variables in "name=value" format.  Note that for security reasons,
 *        these variables are not actually written to the "official"
 *        environmental variable store of the process.
 *
 * return_list : used to return data back to OpenVPN.
 *
 * RETURN VALUE
 *
 * An openvpn_plugin_handle_t value on success, NULL on failure
 */
OPENVPN_PLUGIN_DEF openvpn_plugin_handle_t OPENVPN_PLUGIN_FUNC(openvpn_plugin_open_v2)
     (unsigned int *type_mask,
      const char *argv[],
      const char *envp[],
      struct openvpn_plugin_string_list **return_list);

/*
 * FUNCTION: openvpn_plugin_func_v2
 *
 * Called to perform the work of a given script type.
 *
 * REQUIRED: YES
 * 
 * ARGUMENTS
 *
 * handle : the openvpn_plugin_handle_t value which was returned by
 *          openvpn_plugin_open.
 *
 * type : one of the PLUGIN_x types
 *
 * argv : a NULL-terminated array of "command line" options which
 *        would normally be passed to the script.  argv[0] is the dynamic
 *        library pathname.
 *
 * envp : a NULL-terminated array of OpenVPN-set environmental
 *        variables in "name=value" format.  Note that for security reasons,
 *        these variables are not actually written to the "official"
 *        environmental variable store of the process.
 *
 * per_client_context : the per-client context pointer which was returned by
 *        openvpn_plugin_client_constructor_v1, if defined.
 *
 * return_list : used to return data back to OpenVPN.
 *
 * RETURN VALUE
 *
 * OPENVPN_PLUGIN_FUNC_SUCCESS on success, OPENVPN_PLUGIN_FUNC_ERROR on failure
 *
 * In addition, OPENVPN_PLUGIN_FUNC_DEFERRED may be returned by
 * OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY.  This enables asynchronous
 * authentication where the plugin (or one of its agents) may indicate
 * authentication success/failure some number of seconds after the return
 * of the OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY handler by writing a single
 * char to the file named by auth_control_file in the environmental variable
 * list (envp).
 *
 * first char of auth_control_file:
 * '0' -- indicates auth failure
 * '1' -- indicates auth success
 *
 * OpenVPN will delete the auth_control_file after it goes out of scope.
 *
 * If an OPENVPN_PLUGIN_ENABLE_PF handler is defined and returns success
 * for a particular client instance, packet filtering will be enabled for that
 * instance.  OpenVPN will then attempt to read the packet filter configuration
 * from the temporary file named by the environmental variable pf_file.  This
 * file may be generated asynchronously and may be dynamically updated during the
 * client session, however the client will be blocked from sending or receiving
 * VPN tunnel packets until the packet filter file has been generated.  OpenVPN
 * will periodically test the packet filter file over the life of the client
 * instance and reload when modified.  OpenVPN will delete the packet filter file
 * when the client instance goes out of scope.
 *
 * Packet filter file grammar:
 *
 * [CLIENTS DROP|ACCEPT]
 * {+|-}common_name1
 * {+|-}common_name2
 * . . .
 * [SUBNETS DROP|ACCEPT]
 * {+|-}subnet1
 * {+|-}subnet2
 * . . .
 * [END]
 *
 * Subnet: IP-ADDRESS | IP-ADDRESS/NUM_NETWORK_BITS
 *
 * CLIENTS refers to the set of clients (by their common-name) which
 * this instance is allowed ('+') to connect to, or is excluded ('-')
 * from connecting to.  Note that in the case of client-to-client
 * connections, such communication must be allowed by the packet filter
 * configuration files of both clients.
 *
 * SUBNETS refers to IP addresses or IP address subnets which this
 * instance may connect to ('+') or is excluded ('-') from connecting
 * to.
 *
 * DROP or ACCEPT defines default policy when there is no explicit match
 * for a common-name or subnet.  The [END] tag must exist.  A special
 * purpose tag called [KILL] will immediately kill the client instance.
 * A given client or subnet rule applies to both incoming and outgoing
 * packets.
 *
 * See plugin/defer/simple.c for an example on using asynchronous
 * authentication and client-specific packet filtering.
 */
OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_func_v2)
     (openvpn_plugin_handle_t handle,
      const int type,
      const char *argv[],
      const char *envp[],
      void *per_client_context,
      struct openvpn_plugin_string_list **return_list);

/*
 * FUNCTION: openvpn_plugin_close_v1
 *
 * REQUIRED: YES
 * 
 * ARGUMENTS
 *
 * handle : the openvpn_plugin_handle_t value which was returned by
 *          openvpn_plugin_open.
 *
 * Called immediately prior to plug-in unload.
 */
OPENVPN_PLUGIN_DEF void OPENVPN_PLUGIN_FUNC(openvpn_plugin_close_v1)
     (openvpn_plugin_handle_t handle);

/*
 * FUNCTION: openvpn_plugin_abort_v1
 *
 * REQUIRED: NO
 * 
 * ARGUMENTS
 *
 * handle : the openvpn_plugin_handle_t value which was returned by
 *          openvpn_plugin_open.
 *
 * Called when OpenVPN is in the process of aborting due to a fatal error.
 * Will only be called on an open context returned by a prior successful
 * openvpn_plugin_open callback.
 */
OPENVPN_PLUGIN_DEF void OPENVPN_PLUGIN_FUNC(openvpn_plugin_abort_v1)
     (openvpn_plugin_handle_t handle);

/*
 * FUNCTION: openvpn_plugin_client_constructor_v1
 *
 * Called to allocate a per-client memory region, which
 * is then passed to the openvpn_plugin_func_v2 function.
 * This function is called every time the OpenVPN server
 * constructs a client instance object, which normally
 * occurs when a session-initiating packet is received
 * by a new client, even before the client has authenticated.
 *
 * This function should allocate the private memory needed
 * by the plugin to track individual OpenVPN clients, and
 * return a void * to this memory region.
 *
 * REQUIRED: NO
 * 
 * ARGUMENTS
 *
 * handle : the openvpn_plugin_handle_t value which was returned by
 *          openvpn_plugin_open.
 *
 * RETURN VALUE
 *
 * void * pointer to plugin's private per-client memory region, or NULL
 * if no memory region is required.
 */
OPENVPN_PLUGIN_DEF void * OPENVPN_PLUGIN_FUNC(openvpn_plugin_client_constructor_v1)
     (openvpn_plugin_handle_t handle);

/*
 * FUNCTION: openvpn_plugin_client_destructor_v1
 *
 * This function is called on client instance object destruction.
 *
 * REQUIRED: NO
 * 
 * ARGUMENTS
 *
 * handle : the openvpn_plugin_handle_t value which was returned by
 *          openvpn_plugin_open.
 *
 * per_client_context : the per-client context pointer which was returned by
 *        openvpn_plugin_client_constructor_v1, if defined.
 */
OPENVPN_PLUGIN_DEF void OPENVPN_PLUGIN_FUNC(openvpn_plugin_client_destructor_v1)
     (openvpn_plugin_handle_t handle, void *per_client_context);

/*
 * FUNCTION: openvpn_plugin_select_initialization_point_v1
 *
 * Several different points exist in OpenVPN's initialization sequence where
 * the openvpn_plugin_open function can be called.  While the default is
 * OPENVPN_PLUGIN_INIT_PRE_DAEMON, this function can be used to select a
 * different initialization point.  For example, if your plugin needs to
 * return configuration parameters to OpenVPN, use
 * OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE.
 *
 * REQUIRED: NO
 * 
 * RETURN VALUE:
 *
 * An OPENVPN_PLUGIN_INIT_x value.
 */
#define OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE 1
#define OPENVPN_PLUGIN_INIT_PRE_DAEMON       2 /* default */
#define OPENVPN_PLUGIN_INIT_POST_DAEMON      3
#define OPENVPN_PLUGIN_INIT_POST_UID_CHANGE  4

OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_select_initialization_point_v1)
     (void);

/*
 * FUNCTION: openvpn_plugin_min_version_required_v1
 *
 * This function is called by OpenVPN to query the minimum
   plugin interface version number required by the plugin.
 *
 * REQUIRED: NO
 * 
 * RETURN VALUE
 *
 * The minimum OpenVPN plugin interface version number necessary to support
 * this plugin.
 */
OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_min_version_required_v1)
     (void);

/*
 * Deprecated functions which are still supported for backward compatibility.
 */

OPENVPN_PLUGIN_DEF openvpn_plugin_handle_t OPENVPN_PLUGIN_FUNC(openvpn_plugin_open_v1)
     (unsigned int *type_mask,
      const char *argv[],
      const char *envp[]);

OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_func_v1)
     (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]);