diff options
| -rw-r--r-- | talpid_openvpn_plugin/src/ffi/consts.rs | 55 | ||||
| -rw-r--r-- | talpid_openvpn_plugin/src/ffi/mod.rs | 91 | ||||
| -rw-r--r-- | talpid_openvpn_plugin/src/lib.rs | 6 |
3 files changed, 152 insertions, 0 deletions
diff --git a/talpid_openvpn_plugin/src/ffi/consts.rs b/talpid_openvpn_plugin/src/ffi/consts.rs new file mode 100644 index 0000000000..0861b1b0d8 --- /dev/null +++ b/talpid_openvpn_plugin/src/ffi/consts.rs @@ -0,0 +1,55 @@ +/// Constants for OpenVPN. Taken from include/openvpn-plugin.h in the OpenVPN repository: +/// https://github.com/OpenVPN/openvpn/blob/master/include/openvpn-plugin.h.in + +use std::collections::HashMap; +use std::os::raw::{c_uint, c_int}; + + +// All types of events that a plugin can receive from OpenVPN. +pub const OPENVPN_PLUGIN_UP: c_uint = 0; +pub const OPENVPN_PLUGIN_DOWN: c_uint = 1; +pub const OPENVPN_PLUGIN_ROUTE_UP: c_uint = 2; +pub const OPENVPN_PLUGIN_IPCHANGE: c_uint = 3; +pub const OPENVPN_PLUGIN_TLS_VERIFY: c_uint = 4; +pub const OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY: c_uint = 5; +pub const OPENVPN_PLUGIN_CLIENT_CONNECT: c_uint = 6; +pub const OPENVPN_PLUGIN_CLIENT_DISCONNECT: c_uint = 7; +pub const OPENVPN_PLUGIN_LEARN_ADDRESS: c_uint = 8; +pub const OPENVPN_PLUGIN_CLIENT_CONNECT_V2: c_uint = 9; +pub const OPENVPN_PLUGIN_TLS_FINAL: c_uint = 10; +pub const OPENVPN_PLUGIN_ENABLE_PF: c_uint = 11; +pub const OPENVPN_PLUGIN_ROUTE_PREDOWN: c_uint = 12; +pub const OPENVPN_PLUGIN_N: c_uint = 13; + +lazy_static! { + pub static ref PLUGIN_EVENT_NAMES: HashMap<c_uint, &'static str> = { + let mut map = HashMap::new(); + map.insert(OPENVPN_PLUGIN_UP, "PLUGIN_UP"); + map.insert(OPENVPN_PLUGIN_DOWN, "PLUGIN_DOWN"); + map.insert(OPENVPN_PLUGIN_ROUTE_UP, "PLUGIN_ROUTE_UP"); + map.insert(OPENVPN_PLUGIN_IPCHANGE, "PLUGIN_IPCHANGE"); + map.insert(OPENVPN_PLUGIN_TLS_VERIFY, "PLUGIN_TLS_VERIFY"); + map.insert(OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY, "PLUGIN_AUTH_USER_PASS_VERIFY"); + map.insert(OPENVPN_PLUGIN_CLIENT_CONNECT, "PLUGIN_CLIENT_CONNECT"); + map.insert(OPENVPN_PLUGIN_CLIENT_DISCONNECT, "PLUGIN_CLIENT_DISCONNECT"); + map.insert(OPENVPN_PLUGIN_LEARN_ADDRESS, "PLUGIN_LEARN_ADDRESS"); + map.insert(OPENVPN_PLUGIN_CLIENT_CONNECT_V2, "PLUGIN_CLIENT_CONNECT_V2"); + map.insert(OPENVPN_PLUGIN_TLS_FINAL, "PLUGIN_TLS_FINAL"); + map.insert(OPENVPN_PLUGIN_ENABLE_PF, "PLUGIN_ENABLE_PF"); + map.insert(OPENVPN_PLUGIN_ROUTE_PREDOWN, "PLUGIN_ROUTE_PREDOWN"); + map.insert(OPENVPN_PLUGIN_N, "PLUGIN_N"); + map + }; +} + +/// Returns the name of an OPENVPN_PLUGIN_* constant. +pub fn plugin_event_name(num: c_uint) -> Option<&'static str> { + PLUGIN_EVENT_NAMES.get(&num).map(|s| *s) +} + + +// Return values. Returned from the plugin to OpenVPN to indicate success or failure. Can also +// Accept (success) or decline (error) an operation, such as incoming client connection attempt. +pub const OPENVPN_PLUGIN_FUNC_SUCCESS: c_int = 0; +pub const OPENVPN_PLUGIN_FUNC_ERROR: c_int = 1; +pub const OPENVPN_PLUGIN_FUNC_DEFERRED: c_int = 2; diff --git a/talpid_openvpn_plugin/src/ffi/mod.rs b/talpid_openvpn_plugin/src/ffi/mod.rs new file mode 100644 index 0000000000..eacb87f963 --- /dev/null +++ b/talpid_openvpn_plugin/src/ffi/mod.rs @@ -0,0 +1,91 @@ +/// FFI definitions for OpenVPN. See include/openvpn-plugin.h in the OpenVPN repository for +/// the original declarations of these structs and functions along with documentation for them: +/// https://github.com/OpenVPN/openvpn/blob/master/include/openvpn-plugin.h.in + +use std::os::raw::{c_char, c_int, c_uint, c_void}; + + +#[allow(dead_code)] +mod consts; +use self::consts::*; + + +/// Struct sent to `openvpn_plugin_open_v3` containing input values. +#[repr(C)] +pub struct openvpn_plugin_args_open_in { + type_mask: c_int, + argv: *const *const c_char, + envp: *const *const c_char, + callbacks: *const c_void, + ssl_api: ovpnSSLAPI, + ovpn_version: *const c_char, + ovpn_version_major: c_uint, + ovpn_version_minor: c_uint, + ovpn_version_patch: *const c_char, +} + +#[allow(dead_code)] +#[repr(C)] +enum ovpnSSLAPI { + SSLAPI_NONE, + SSLAPI_OPENSSL, + SSLAPI_MBEDTLS, +} + +/// Struct used for returning values from `openvpn_plugin_open_v3` to OpenVPN. +#[repr(C)] +pub struct openvpn_plugin_args_open_return { + type_mask: c_int, + handle: *const c_void, + return_list: *const c_void, +} + +/// Struct sent to `openvpn_plugin_func_v3` containing input values. +#[repr(C)] +pub struct openvpn_plugin_args_func_in { + event_type: c_int, + argv: *const *const c_char, + envp: *const *const c_char, + handle: *const c_void, + per_client_context: *const c_void, + current_cert_depth: c_int, + current_cert: *const c_void, +} + +/// Struct used for returning values from `openvpn_plugin_func_v3` to OpenVPN. +#[repr(C)] +pub struct openvpn_plugin_args_func_return { + return_list: *const c_void, +} + + +/// Called by OpenVPN when the plugin is first loaded. +/// Used to register which events the plugin wants to listen to (`type_mask`). Can also return an +/// arbitrary object inside `handle` that will then be passed to all subsequent calls to the +/// plugin. +#[no_mangle] +pub extern "C" fn openvpn_plugin_open_v3(version: c_int, + _arguments: *const openvpn_plugin_args_open_in, + _retptr: *const openvpn_plugin_args_open_return) + -> c_int { + println!("openvpn_plugin_open_v3(version: {})", version); + OPENVPN_PLUGIN_FUNC_SUCCESS +} + +/// Called by OpenVPN just before the plugin is unloaded. Should correctly close the plugin and +/// deallocate any `handle` initialized by the plugin in `openvpn_plugin_open_v3` +#[no_mangle] +pub extern "C" fn openvpn_plugin_close_v1(handle: *const c_void) { + println!("openvpn_plugin_close_v1(handle: {:p})", handle); +} + +/// Called by OpenVPN for each OPENVPN_PLUGIN_* event that it registered for in +/// `openvpn_plugin_open_v3` +#[no_mangle] +pub extern "C" fn openvpn_plugin_func_v3(version: c_int, + _arguments: *const openvpn_plugin_args_func_in, + _retptr: *const openvpn_plugin_args_func_return) + -> c_int { + println!("openvpn_plugin_func_v3(version: {})", version); + OPENVPN_PLUGIN_FUNC_SUCCESS +} diff --git a/talpid_openvpn_plugin/src/lib.rs b/talpid_openvpn_plugin/src/lib.rs index 656405efb7..a917ead7a5 100644 --- a/talpid_openvpn_plugin/src/lib.rs +++ b/talpid_openvpn_plugin/src/lib.rs @@ -1,2 +1,8 @@ #[macro_use] extern crate lazy_static; + +mod ffi; + +/// Publicly export the functions making up the public interface of the plugin. These are the C FFI +/// functions called by OpenVPN. +pub use ffi::{openvpn_plugin_open_v3, openvpn_plugin_close_v1, openvpn_plugin_func_v3}; |
