add API for plug-ins to write to openvpn log

Some plugins want to add messages to the openvpn log file. The
plugin_log() and plugin_vlog() APIs provide ways for them to do so.

OPENVPN_PLUGINv3_STRUCTVER is not incremented as the v3 plugin API
is new in 2.3 and this is merged during alpha phase.

Signed-off-by: Heiko Hund <heiko.hund@sophos.com>
Acked-by: David Sommerseth <davids@redhat.com>
Message-Id: 1343920822-29161-1-git-send-email-heiko.hund@sophos.com
URL: http://article.gmane.org/gmane.network.openvpn.devel/6946
Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>
This commit is contained in:
Heiko Hund 2012-08-02 17:20:22 +02:00 committed by David Sommerseth
parent 004ca97c94
commit be532e0d15
2 changed files with 121 additions and 2 deletions

View file

@ -43,6 +43,8 @@ typedef X509 openvpn_x509_cert_t;
#endif
#endif
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -145,7 +147,7 @@ typedef void *openvpn_plugin_handle_t;
/*
* For Windows (needs to be modified for MSVC)
*/
#if defined(__MINGW32_VERSION) && !defined(OPENVPN_PLUGIN_H)
#if defined(WIN32) && !defined(OPENVPN_PLUGIN_H)
# define OPENVPN_EXPORT __declspec(dllexport)
#else
# define OPENVPN_EXPORT
@ -204,6 +206,59 @@ struct openvpn_plugin_string_list
*/
#define OPENVPN_PLUGINv3_STRUCTVER 1
/**
* Definitions needed for the plug-in callback functions.
*/
typedef enum
{
PLOG_ERR = (1 << 0), /* Error condition message */
PLOG_WARN = (1 << 1), /* General warning message */
PLOG_NOTE = (1 << 2), /* Informational message */
PLOG_DEBUG = (1 << 3), /* Debug message, displayed if verb >= 7 */
PLOG_ERRNO = (1 << 8), /* Add error description to message */
PLOG_NOMUTE = (1 << 9), /* Mute setting does not apply for message */
} openvpn_plugin_log_flags_t;
#ifdef __GNUC__
#if __USE_MINGW_ANSI_STDIO
# define _ovpn_chk_fmt(a, b) __attribute__ ((format(gnu_printf, (a), (b))))
#else
# define _ovpn_chk_fmt(a, b) __attribute__ ((format(__printf__, (a), (b))))
#endif
#else
# define _ovpn_chk_fmt(a, b)
#endif
typedef void (*plugin_log_t) (openvpn_plugin_log_flags_t flags,
const char *plugin_name,
const char *format, ...) _ovpn_chk_fmt(3, 4);
typedef void (*plugin_vlog_t) (openvpn_plugin_log_flags_t flags,
const char *plugin_name,
const char *format,
va_list arglist) _ovpn_chk_fmt(3, 0);
#undef _ovpn_chk_fmt
/**
* Used by the openvpn_plugin_open_v3() function to pass callback
* function pointers to the plug-in.
*
* plugin_log
* plugin_vlog : Use these functions to add information to the OpenVPN log file.
* Messages will only be displayed if the plugin_name parameter
* is set. PLOG_DEBUG messages will only be displayed with plug-in
* debug log verbosity (at the time of writing that's verb >= 7).
*/
struct openvpn_plugin_callbacks
{
plugin_log_t plugin_log;
plugin_vlog_t plugin_vlog;
};
/**
* Arguments used to transport variables to the plug-in.
* The struct openvpn_plugin_args_open_in is only used
@ -221,12 +276,16 @@ struct openvpn_plugin_string_list
* 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.
*
* callbacks : a pointer to the plug-in callback function struct.
*
*/
struct openvpn_plugin_args_open_in
{
const int type_mask;
const char ** const argv;
const char ** const envp;
struct openvpn_plugin_callbacks *callbacks;
};

View file

@ -286,6 +286,65 @@ plugin_init_item (struct plugin *p, const struct plugin_option *o)
gc_free (&gc);
}
static void
plugin_vlog (openvpn_plugin_log_flags_t flags, const char *name, const char *format, va_list arglist)
{
unsigned int msg_flags;
if (!format)
return;
if (!name || name[0] == '\0')
{
msg (D_PLUGIN_DEBUG, "PLUGIN: suppressed log message from plugin with unknown name");
return;
}
if (flags & PLOG_ERR)
msg_flags = M_INFO | M_NONFATAL;
else if (flags & PLOG_WARN)
msg_flags = M_INFO | M_WARN;
else if (flags & PLOG_NOTE)
msg_flags = M_INFO;
else if (flags & PLOG_DEBUG)
msg_flags = D_PLUGIN_DEBUG;
if (flags & PLOG_ERRNO)
msg_flags |= M_ERRNO;
if (flags & PLOG_NOMUTE)
msg_flags |= M_NOMUTE;
if (MSG_TEST (msg_flags))
{
struct gc_arena gc;
char* msg_fmt;
/* Never add instance prefix; not thread safe */
msg_flags |= M_NOIPREFIX;
gc_init (&gc);
msg_fmt = gc_malloc (ERR_BUF_SIZE, false, &gc);
openvpn_snprintf (msg_fmt, ERR_BUF_SIZE, "PLUGIN %s: %s", name, format);
x_msg_va (msg_flags, msg_fmt, arglist);
gc_free (&gc);
}
}
static void
plugin_log (openvpn_plugin_log_flags_t flags, const char *name, const char *format, ...)
{
va_list arglist;
va_start (arglist, format);
plugin_vlog (flags, name, format, arglist);
va_end (arglist);
}
static struct openvpn_plugin_callbacks callbacks = {
plugin_log,
plugin_vlog
};
static void
plugin_open_item (struct plugin *p,
const struct plugin_option *o,
@ -312,7 +371,8 @@ plugin_open_item (struct plugin *p,
if (p->open3) {
struct openvpn_plugin_args_open_in args = { p->plugin_type_mask,
(const char ** const) o->argv,
(const char ** const) envp };
(const char ** const) envp,
&callbacks };
struct openvpn_plugin_args_open_return retargs;
CLEAR(retargs);