OpenVPN
base64.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2017-2024 David Sommerseth <davids@openvpn.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <stdio.h>
26#include <string.h>
27#include <stdlib.h>
28
29#include "openvpn-plugin.h"
30
31#define PLUGIN_NAME "base64.c"
32
33/* Exported plug-in v3 API functions */
34plugin_log_t ovpn_log = NULL;
35plugin_vlog_t ovpn_vlog = NULL;
36plugin_base64_encode_t ovpn_base64_encode = NULL;
37plugin_base64_decode_t ovpn_base64_decode = NULL;
53static const char *
54get_env(const char *name, const char *envp[])
55{
56 if (envp)
57 {
58 int i;
59 const int namelen = strlen(name);
60 for (i = 0; envp[i]; ++i)
61 {
62 if (!strncmp(envp[i], name, namelen))
63 {
64 const char *cp = envp[i] + namelen;
65 if (*cp == '=')
66 {
67 return cp + 1;
68 }
69 }
70 }
71 }
72 return NULL;
73}
74
75
98OPENVPN_EXPORT int
99openvpn_plugin_open_v3(const int v3structver,
100 struct openvpn_plugin_args_open_in const *args,
101 struct openvpn_plugin_args_open_return *ret)
102{
103 /* Check that we are API compatible */
104 if (v3structver != OPENVPN_PLUGINv3_STRUCTVER)
105 {
106 printf("base64.c: ** ERROR ** Incompatible plug-in interface between this plug-in and OpenVPN\n");
107 return OPENVPN_PLUGIN_FUNC_ERROR;
108 }
109
110 /* Which callbacks to intercept. */
111 ret->type_mask =
112 OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_TLS_VERIFY)
113 |OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_CONNECT_V2);
114
115 /* we don't need a plug-in context in this example, but OpenVPN expects "something" */
116 ret->handle = calloc(1, 1);
117
118 /* Hook into the exported functions from OpenVPN */
119 ovpn_log = args->callbacks->plugin_log;
120 ovpn_vlog = args->callbacks->plugin_vlog;
121 ovpn_base64_encode = args->callbacks->plugin_base64_encode;
122 ovpn_base64_decode = args->callbacks->plugin_base64_decode;
123
124 /* Print some version information about the OpenVPN process using this plug-in */
125 ovpn_log(PLOG_NOTE, PLUGIN_NAME, "OpenVPN %s (Major: %i, Minor: %i, Patch: %s)\n",
126 args->ovpn_version, args->ovpn_version_major,
127 args->ovpn_version_minor, args->ovpn_version_patch);
128
129 return OPENVPN_PLUGIN_FUNC_SUCCESS;
130}
131
132
154OPENVPN_EXPORT int
155openvpn_plugin_func_v1(openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[])
156{
157 if (type != OPENVPN_PLUGIN_TLS_VERIFY
158 && type != OPENVPN_PLUGIN_CLIENT_CONNECT_V2)
159 {
160 ovpn_log(PLOG_ERR, PLUGIN_NAME, "Unsupported plug-in hook call attempted");
161 return OPENVPN_PLUGIN_FUNC_ERROR;
162 }
163
164 /* get username/password from envp string array */
165 const char *clcert_cn = get_env("X509_0_CN", envp);
166 if (!clcert_cn)
167 {
168 /* Ignore certificate checks not being a client certificate */
169 return OPENVPN_PLUGIN_FUNC_SUCCESS;
170 }
171
172 /* test the BASE64 encode function */
173 char *buf = NULL;
174 int r = ovpn_base64_encode(clcert_cn, strlen(clcert_cn), &buf);
175 ovpn_log(PLOG_NOTE, PLUGIN_NAME, "BASE64 encoded '%s' (return value %i): '%s'",
176 clcert_cn, r, buf);
177
178 /* test the BASE64 decode function */
179 char buf2[256] = {0};
180 r = ovpn_base64_decode(buf, &buf2, 255);
181 ovpn_log(PLOG_NOTE, PLUGIN_NAME, "BASE64 decoded '%s' (return value %i): '%s'",
182 buf, r, buf2);
183
184 /* Verify the result, and free the buffer allocated by ovpn_base64_encode() */
185 r = strcmp(clcert_cn, buf2);
186 free(buf);
187
188 return (r == 0) ? OPENVPN_PLUGIN_FUNC_SUCCESS : OPENVPN_PLUGIN_FUNC_ERROR;
189}
190
191
199OPENVPN_EXPORT void
200openvpn_plugin_close_v1(openvpn_plugin_handle_t handle)
201{
202 struct plugin_context *context = (struct plugin_context *) handle;
203 free(context);
204}
OPENVPN_EXPORT int openvpn_plugin_func_v1(openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[])
This function is called by OpenVPN each time the OpenVPN reaches a point where plug-in calls should h...
Definition base64.c:155
OPENVPN_EXPORT void openvpn_plugin_close_v1(openvpn_plugin_handle_t handle)
This cleans up the last part of the plug-in, allows it to shut down cleanly and release the plug-in g...
Definition base64.c:200
#define PLUGIN_NAME
Definition base64.c:31
plugin_log_t ovpn_log
Pointer to the OpenVPN log function.
Definition base64.c:34
plugin_base64_decode_t ovpn_base64_decode
Pointer to the openvpn_base64_decode () function.
Definition base64.c:37
plugin_base64_encode_t ovpn_base64_encode
Pointer to the openvpn_base64_encode () function.
Definition base64.c:36
plugin_vlog_t ovpn_vlog
Pointer to the OpenVPN vlog function.
Definition base64.c:35
static const char * get_env(const char *name, const char *envp[])
Search the environment pointer for a specific env var name.
Definition base64.c:54
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)
This function is called when OpenVPN loads the plug-in.
Definition base64.c:99
Definition argv.h:35
Contains all state information for one tunnel.
Definition openvpn.h:474