summaryrefslogtreecommitdiffhomepage
path: root/talpid_openvpn_plugin/src
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2017-01-17 17:38:16 +0100
committerLinus Färnstrand <linus@mullvad.net>2017-01-30 10:07:26 +0100
commit2cb2c446e45bf4afaa80ee57cb76957c6436f873 (patch)
tree78a827b6e2480a524f3ecf59b6bd8113dff8e227 /talpid_openvpn_plugin/src
parentdeff9f3fc4d4627b07e25bb43eb9a70a0129acaa (diff)
downloadmullvadvpn-2cb2c446e45bf4afaa80ee57cb76957c6436f873.tar.xz
mullvadvpn-2cb2c446e45bf4afaa80ee57cb76957c6436f873.zip
Add initial FFI declarations for an OpenVPN plugin
Diffstat (limited to 'talpid_openvpn_plugin/src')
-rw-r--r--talpid_openvpn_plugin/src/ffi/consts.rs55
-rw-r--r--talpid_openvpn_plugin/src/ffi/mod.rs91
-rw-r--r--talpid_openvpn_plugin/src/lib.rs6
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};