mirror of
https://github.com/OpenVPN/openvpn.git
synced 2026-05-28 04:03:29 -04:00
plugin: Export base64 encode and decode functions
This patch builds on the "Export secure_memzero() to plug-ins" patch and adds export of openvpn_base64_encode() and openvpn_base64_decode() This also ships with a very simple plug-in which demonstrates how to use the new exported functions. Signed-off-by: David Sommerseth <davids@openvpn.net> Acked-by: Selva Nair <selva.nair@gmail.com> Message-Id: <20170505214624.11675-1-davids@openvpn.net> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14558.html Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
parent
ae950fac83
commit
6690769f78
3 changed files with 238 additions and 1 deletions
|
|
@ -219,6 +219,8 @@ struct openvpn_plugin_string_list
|
|||
* OpenVPN to plug-ins.
|
||||
*
|
||||
* 4 Exported secure_memzero() as plugin_secure_memzero()
|
||||
* Exported openvpn_base64_encode() as plugin_base64_encode()
|
||||
* Exported openvpn_base64_decode() as plugin_base64_decode()
|
||||
*/
|
||||
#define OPENVPN_PLUGINv3_STRUCTVER 4
|
||||
|
||||
|
|
@ -267,6 +269,33 @@ typedef void (*plugin_vlog_t)(openvpn_plugin_log_flags_t flags,
|
|||
*/
|
||||
typedef void (*plugin_secure_memzero_t)(void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Export of openvpn_base64_encode() to be used inside plug-ins
|
||||
*
|
||||
* @param data Pointer to data to BASE64 encode
|
||||
* @param size Length of data, in bytes
|
||||
* @param *str Pointer to the return buffer. This needed memory is
|
||||
* allocated by openvpn_base64_encode() and needs to be free()d
|
||||
* after use.
|
||||
*
|
||||
* @return int Returns the length of the buffer created, or -1 on error.
|
||||
*
|
||||
*/
|
||||
typedef int (*plugin_base64_encode_t)(const void *data, int size, char **str);
|
||||
|
||||
/**
|
||||
* Export of openvpn_base64_decode() to be used inside plug-ins
|
||||
*
|
||||
* @param str Pointer to the BASE64 encoded data
|
||||
* @param data Pointer to the buffer where save the decoded data
|
||||
* @param size Size of the destination buffer
|
||||
*
|
||||
* @return int Returns the length of the decoded data, or -1 on error or
|
||||
* if the destination buffer is too small.
|
||||
*
|
||||
*/
|
||||
typedef int (*plugin_base64_decode_t)(const char *str, void *data, int size);
|
||||
|
||||
|
||||
/**
|
||||
* Used by the openvpn_plugin_open_v3() function to pass callback
|
||||
|
|
@ -289,6 +318,8 @@ struct openvpn_plugin_callbacks
|
|||
plugin_log_t plugin_log;
|
||||
plugin_vlog_t plugin_vlog;
|
||||
plugin_secure_memzero_t plugin_secure_memzero;
|
||||
plugin_base64_encode_t plugin_base64_encode;
|
||||
plugin_base64_decode_t plugin_base64_decode;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
203
sample/sample-plugins/simple/base64.c
Normal file
203
sample/sample-plugins/simple/base64.c
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* 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) 2017 David Sommerseth <davids@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
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "openvpn-plugin.h"
|
||||
|
||||
#define PLUGIN_NAME "base64.c"
|
||||
|
||||
/* Exported plug-in v3 API functions */
|
||||
plugin_log_t ovpn_log = NULL; /**< Pointer to the OpenVPN log function. See plugin_log() */
|
||||
plugin_vlog_t ovpn_vlog = NULL; /**< Pointer to the OpenVPN vlog function. See plugin_vlog() */
|
||||
plugin_base64_encode_t ovpn_base64_encode = NULL; /**< Pointer to the openvpn_base64_encode () function */
|
||||
plugin_base64_decode_t ovpn_base64_decode = NULL; /**< Pointer to the openvpn_base64_decode () function */
|
||||
|
||||
/**
|
||||
* Search the environment pointer for a specific env var name
|
||||
*
|
||||
* PLEASE NOTE! The result is not valid outside the local
|
||||
* scope of the calling function. Once the calling function
|
||||
* returns, any returned pointers are invalid.
|
||||
*
|
||||
* @param name String containing the env.var name to search for
|
||||
* @param envp String array pointer to the environment variable
|
||||
*
|
||||
* @return Returns a pointer to the value in the environment variable
|
||||
* table on successful match. Otherwise NULL is returned
|
||||
*
|
||||
*/
|
||||
static const char *
|
||||
get_env(const char *name, const char *envp[])
|
||||
{
|
||||
if (envp)
|
||||
{
|
||||
int i;
|
||||
const int namelen = strlen(name);
|
||||
for (i = 0; envp[i]; ++i)
|
||||
{
|
||||
if (!strncmp(envp[i], name, namelen))
|
||||
{
|
||||
const char *cp = envp[i] + namelen;
|
||||
if (*cp == '=')
|
||||
{
|
||||
return cp + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is called when OpenVPN loads the plug-in.
|
||||
* The purpose is to initialize the plug-in and tell OpenVPN
|
||||
* which plug-in hooks this plug-in wants to be involved in
|
||||
*
|
||||
* For the arguments, see the include/openvpn-plugin.h file
|
||||
* for details on the function parameters
|
||||
*
|
||||
* @param v3structver An integer containing the API version of
|
||||
* the plug-in structs OpenVPN uses
|
||||
* @param args A pointer to the argument struct for
|
||||
* information and features provided by
|
||||
* OpenVPN to the plug-in
|
||||
* @param ret A pointer to the struct OpenVPN uses to
|
||||
* receive information back from the plug-in
|
||||
*
|
||||
* @return Must return OPENVPN_PLUGIN_FUNC_SUCCESS when everything
|
||||
* completed successfully. Otherwise it must be returned
|
||||
* OPENVPN_PLUGIN_FUNC_ERROR, which will stop OpenVPN
|
||||
* from running
|
||||
*
|
||||
*/
|
||||
OPENVPN_EXPORT int
|
||||
openvpn_plugin_open_v3(const int v3structver,
|
||||
struct openvpn_plugin_args_open_in const *args,
|
||||
struct openvpn_plugin_args_open_return *ret)
|
||||
{
|
||||
/* Check that we are API compatible */
|
||||
if (v3structver != OPENVPN_PLUGINv3_STRUCTVER)
|
||||
{
|
||||
printf("base64.c: ** ERROR ** Incompatible plug-in interface between this plug-in and OpenVPN\n");
|
||||
return OPENVPN_PLUGIN_FUNC_ERROR;
|
||||
}
|
||||
|
||||
/* Which callbacks to intercept. */
|
||||
ret->type_mask =
|
||||
OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_TLS_VERIFY)
|
||||
|OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_CONNECT_V2);
|
||||
|
||||
/* we don't need a plug-in context in this example, but OpenVPN expects "something" */
|
||||
ret->handle = calloc(1, 1);
|
||||
|
||||
/* Hook into the exported functions from OpenVPN */
|
||||
ovpn_log = args->callbacks->plugin_log;
|
||||
ovpn_vlog = args->callbacks->plugin_vlog;
|
||||
ovpn_base64_encode = args->callbacks->plugin_base64_encode;
|
||||
ovpn_base64_decode = args->callbacks->plugin_base64_decode;
|
||||
|
||||
/* Print some version information about the OpenVPN process using this plug-in */
|
||||
ovpn_log(PLOG_NOTE, PLUGIN_NAME, "OpenVPN %s (Major: %i, Minor: %i, Patch: %s)\n",
|
||||
args->ovpn_version, args->ovpn_version_major,
|
||||
args->ovpn_version_minor, args->ovpn_version_patch);
|
||||
|
||||
return OPENVPN_PLUGIN_FUNC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is called by OpenVPN each time the OpenVPN reaches
|
||||
* a point where plug-in calls should happen. It only happens for those
|
||||
* plug-in hooks enabled in openvpn_plugin_open_v3().
|
||||
*
|
||||
* For the arguments, see the include/openvpn-plugin.h file
|
||||
* for details on the function parameters
|
||||
*
|
||||
* @param args Pointer to a struct with details about the plug-in
|
||||
* call from the main OpenVPN process.
|
||||
* @param returndata Pointer to a struct where the plug-in can provide
|
||||
* information back to OpenVPN to be processed
|
||||
*
|
||||
* @return Must return OPENVPN_PLUGIN_FUNC_SUCCESS or
|
||||
* OPENVPN_PLUGIN_FUNC_DEFERRED on success. Otherwise it
|
||||
* should return OPENVPN_FUNC_ERROR, which will stop and reject
|
||||
* the client session from progressing.
|
||||
*
|
||||
*/
|
||||
|
||||
OPENVPN_EXPORT int
|
||||
openvpn_plugin_func_v1(openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[])
|
||||
{
|
||||
if (type != OPENVPN_PLUGIN_TLS_VERIFY
|
||||
&& type != OPENVPN_PLUGIN_CLIENT_CONNECT_V2)
|
||||
{
|
||||
ovpn_log(PLOG_ERR, PLUGIN_NAME, "Unsupported plug-in hook call attempted");
|
||||
return OPENVPN_PLUGIN_FUNC_ERROR;
|
||||
}
|
||||
|
||||
/* get username/password from envp string array */
|
||||
const char *clcert_cn = get_env("X509_0_CN", envp);
|
||||
if (!clcert_cn)
|
||||
{
|
||||
/* Ignore certificate checks not being a client certificate */
|
||||
return OPENVPN_PLUGIN_FUNC_SUCCESS;
|
||||
}
|
||||
|
||||
/* test the BASE64 encode function */
|
||||
char *buf = NULL;
|
||||
int r = ovpn_base64_encode(clcert_cn, strlen(clcert_cn), &buf);
|
||||
ovpn_log(PLOG_NOTE, PLUGIN_NAME, "BASE64 encoded '%s' (return value %i): '%s'",
|
||||
clcert_cn, r, buf);
|
||||
|
||||
/* test the BASE64 decode function */
|
||||
char buf2[256] = {0};
|
||||
r = ovpn_base64_decode(buf, &buf2, 255);
|
||||
ovpn_log(PLOG_NOTE, PLUGIN_NAME, "BASE64 decoded '%s' (return value %i): '%s'",
|
||||
buf, r, buf2);
|
||||
|
||||
/* Verify the result, and free the buffer allocated by ovpn_base64_encode() */
|
||||
r = strcmp(clcert_cn, buf2);
|
||||
free(buf);
|
||||
|
||||
return (r == 0) ? OPENVPN_PLUGIN_FUNC_SUCCESS : OPENVPN_PLUGIN_FUNC_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This cleans up the last part of the plug-in, allows it to
|
||||
* shut down cleanly and release the plug-in global context buffer
|
||||
*
|
||||
* @param handle Pointer to the plug-in global context buffer, which
|
||||
* need to be released by this function
|
||||
*/
|
||||
OPENVPN_EXPORT void
|
||||
openvpn_plugin_close_v1(openvpn_plugin_handle_t handle)
|
||||
{
|
||||
struct plugin_context *context = (struct plugin_context *) handle;
|
||||
free(context);
|
||||
}
|
||||
|
|
@ -43,6 +43,7 @@
|
|||
#include "misc.h"
|
||||
#include "plugin.h"
|
||||
#include "ssl_backend.h"
|
||||
#include "base64.h"
|
||||
#include "win32.h"
|
||||
#include "memdbg.h"
|
||||
|
||||
|
|
@ -410,7 +411,9 @@ plugin_log(openvpn_plugin_log_flags_t flags, const char *name, const char *forma
|
|||
static struct openvpn_plugin_callbacks callbacks = {
|
||||
plugin_log,
|
||||
plugin_vlog,
|
||||
secure_memzero /* plugin_secure_memzero */
|
||||
secure_memzero, /* plugin_secure_memzero */
|
||||
openvpn_base64_encode, /* plugin_base64_encode */
|
||||
openvpn_base64_decode, /* plugin_base64_decode */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue