summaryrefslogtreecommitdiff
path: root/sample
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff.email>2021-11-29 20:51:58 +0100
committerJörg Frings-Fürst <debian@jff.email>2021-11-29 20:51:58 +0100
commit6e3e95a9da9458ddf0874b4bd1c8ce6b47fcef27 (patch)
tree6e3667709d99f857d90b9831426f6a32ee70d113 /sample
parentb29f419d68b26b75a44e3ac00748875f1003b900 (diff)
parentf2b3dda12a731c2e0971cb7889728edaf23f6cb0 (diff)
Merge branch 'upstream' into develop
Diffstat (limited to 'sample')
-rw-r--r--sample/Makefile.am5
-rw-r--r--sample/Makefile.in18
-rw-r--r--sample/sample-config-files/client.conf4
-rw-r--r--sample/sample-config-files/loopback-client208
-rw-r--r--sample/sample-config-files/loopback-server1
-rw-r--r--sample/sample-config-files/server.conf2
-rw-r--r--sample/sample-config-files/static-home.conf75
-rw-r--r--sample/sample-config-files/static-office.conf72
-rw-r--r--sample/sample-config-files/tls-home.conf12
-rw-r--r--sample/sample-config-files/tls-office.conf3
-rwxr-xr-xsample/sample-keys/gen-sample-keys.sh4
-rw-r--r--sample/sample-keys/openssl.cnf4
-rw-r--r--sample/sample-plugins/Makefile585
-rw-r--r--sample/sample-plugins/Makefile.am34
-rw-r--r--sample/sample-plugins/Makefile.in585
-rw-r--r--sample/sample-plugins/Makefile.plugins37
-rw-r--r--sample/sample-plugins/README43
-rw-r--r--sample/sample-plugins/client-connect/README38
-rw-r--r--sample/sample-plugins/client-connect/sample-client-connect.c612
-rw-r--r--sample/sample-plugins/defer/README16
-rwxr-xr-xsample/sample-plugins/defer/build15
-rw-r--r--sample/sample-plugins/defer/simple.c400
-rwxr-xr-xsample/sample-plugins/keying-material-exporter-demo/build15
-rw-r--r--sample/sample-plugins/keying-material-exporter-demo/keyingmaterialexporter.c16
-rwxr-xr-xsample/sample-plugins/log/build15
-rw-r--r--sample/sample-plugins/log/log.c11
-rw-r--r--sample/sample-plugins/log/log_v3.c17
-rw-r--r--sample/sample-plugins/simple/README16
-rw-r--r--sample/sample-plugins/simple/base64.c2
-rwxr-xr-xsample/sample-plugins/simple/build15
-rw-r--r--sample/sample-plugins/simple/simple.c7
-rwxr-xr-xsample/sample-windows/sample.ovpn2
32 files changed, 2514 insertions, 375 deletions
diff --git a/sample/Makefile.am b/sample/Makefile.am
index 3be698e..06ba0ff 100644
--- a/sample/Makefile.am
+++ b/sample/Makefile.am
@@ -5,13 +5,16 @@
# packet encryption, packet authentication, and
# packet compression.
#
-# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
+# Copyright (C) 2002-2021 OpenVPN Inc <sales@openvpn.net>
# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com>
#
MAINTAINERCLEANFILES = \
$(srcdir)/Makefile.in
+DISTCLEANFILES = \
+ $(builddir)/sample-plugins/Makefile
+
EXTRA_DIST = \
sample-plugins \
sample-config-files \
diff --git a/sample/Makefile.in b/sample/Makefile.in
index d851a5f..3c9335f 100644
--- a/sample/Makefile.in
+++ b/sample/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -21,7 +21,7 @@
# packet encryption, packet authentication, and
# packet compression.
#
-# Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
+# Copyright (C) 2002-2021 OpenVPN Inc <sales@openvpn.net>
# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com>
#
@@ -179,7 +179,8 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
-CMAKE = @CMAKE@
+CMOCKA_CFLAGS = @CMOCKA_CFLAGS@
+CMOCKA_LIBS = @CMOCKA_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -193,6 +194,7 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
+ENABLE_UNITTESTS = @ENABLE_UNITTESTS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GIT = @GIT@
@@ -220,7 +222,6 @@ LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
-MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
MBEDTLS_LIBS = @MBEDTLS_LIBS@
@@ -271,6 +272,8 @@ PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
+RST2HTML = @RST2HTML@
+RST2MAN = @RST2MAN@
SED = @SED@
SELINUX_LIBS = @SELINUX_LIBS@
SET_MAKE = @SET_MAKE@
@@ -334,6 +337,7 @@ plugindir = @plugindir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
+runstatedir = @runstatedir@
sampledir = @sampledir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
@@ -348,6 +352,9 @@ top_srcdir = @top_srcdir@
MAINTAINERCLEANFILES = \
$(srcdir)/Makefile.in
+DISTCLEANFILES = \
+ $(builddir)/sample-plugins/Makefile
+
EXTRA_DIST = \
sample-plugins \
sample-config-files \
@@ -492,6 +499,7 @@ clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
diff --git a/sample/sample-config-files/client.conf b/sample/sample-config-files/client.conf
index 5fd4a94..47ca409 100644
--- a/sample/sample-config-files/client.conf
+++ b/sample/sample-config-files/client.conf
@@ -90,7 +90,7 @@ cert client.crt
key client.key
# Verify server certificate by checking that the
-# certicate has the correct key usage set.
+# certificate has the correct key usage set.
# This is an important precaution to protect against
# a potential attack discussed here:
# http://openvpn.net/howto.html#mitm
@@ -112,7 +112,7 @@ tls-auth ta.key 1
# then you must also specify it here.
# Note that v2.4 client/server will automatically
# negotiate AES-256-GCM in TLS mode.
-# See also the ncp-cipher option in the manpage
+# See also the data-ciphers option in the manpage
cipher AES-256-CBC
# Enable compression on the VPN link.
diff --git a/sample/sample-config-files/loopback-client b/sample/sample-config-files/loopback-client
index 7117307..8ac3d1d 100644
--- a/sample/sample-config-files/loopback-client
+++ b/sample/sample-config-files/loopback-client
@@ -8,6 +8,9 @@
#
# ./openvpn --config sample-config-files/loopback-client (In one window)
# ./openvpn --config sample-config-files/loopback-server (Simultaneously in another window)
+#
+# this config file has the crypto material (cert, key, ..) "inlined",
+# while the "server" config has it as external reference - test both paths
rport 16000
lport 16001
@@ -18,9 +21,206 @@ verb 3
reneg-sec 10
tls-client
remote-cert-tls server
-ca sample-keys/ca.crt
-key sample-keys/client.key
-cert sample-keys/client.crt
-tls-auth sample-keys/ta.key 1
+#ca sample-keys/ca.crt
+<ca>
+-----BEGIN CERTIFICATE-----
+MIIGKDCCBBCgAwIBAgIJAKFO3vqQ8q6BMA0GCSqGSIb3DQEBCwUAMGYxCzAJBgNV
+BAYTAktHMQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UEChMM
+T3BlblZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4w
+HhcNMTQxMDIyMjE1OTUyWhcNMjQxMDE5MjE1OTUyWjBmMQswCQYDVQQGEwJLRzEL
+MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
+VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMIICIjANBgkq
+hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsJVPCqt3vtoDW2U0DII1QIh2Qs0dqh88
+8nivxAIm2LTq93e9fJhsq3P/UVYAYSeCIrekXypR0EQgSgcNTvGBMe20BoHO5yvb
+GjKPmjfLj6XRotCOGy8EDl/hLgRY9efiA8wsVfuvF2q/FblyJQPR/gPiDtTmUiqF
+qXa7AJmMrqFsnWppOuGd7Qc6aTsae4TF1e/gUTCTraa7NeHowDaKhdyFmEEnCYR5
+CeUsx2JlFWAH8PCrxBpHYbmGyvS0kH3+rQkaSM/Pzc2bS4ayHaOYRK5XsGq8XiNG
+KTTLnSaCdPeHsI+3xMHmEh+u5Og2DFGgvyD22gde6W2ezvEKCUDrzR7bsnYqqyUy
+n7LxnkPXGyvR52T06G8KzLKQRmDlPIXhzKMO07qkHmIonXTdF7YI1azwHpAtN4dS
+rUe1bvjiTSoEsQPfOAyvD0RMK/CBfgEZUzAB50e/IlbZ84c0DJfUMOm4xCyft1HF
+YpYeyCf5dxoIjweCPOoP426+aTXM7kqq0ieIr6YxnKV6OGGLKEY+VNZh1DS7enqV
+HP5i8eimyuUYPoQhbK9xtDGMgghnc6Hn8BldPMcvz98HdTEH4rBfA3yNuCxLSNow
+4jJuLjNXh2QeiUtWtkXja7ec+P7VqKTduJoRaX7cs+8E3ImigiRnvmK+npk7Nt1y
+YE9hBRhSoLsCAwEAAaOB2DCB1TAdBgNVHQ4EFgQUK0DlyX319JY46S/jL9lAZMmO
+BZswgZgGA1UdIwSBkDCBjYAUK0DlyX319JY46S/jL9lAZMmOBZuhaqRoMGYxCzAJ
+BgNVBAYTAktHMQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UE
+ChMMT3BlblZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21h
+aW6CCQChTt76kPKugTAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG
+9w0BAQsFAAOCAgEABc77f4C4P8fIS+V8qCJmVNSDU44UZBc+D+J6ZTgW8JeOHUIj
+Bh++XDg3gwat7pIWQ8AU5R7h+fpBI9n3dadyIsMHGwSogHY9Gw7di2RVtSFajEth
+rvrq0JbzpwoYedMh84sJ2qI/DGKW9/Is9+O52fR+3z3dY3gNRDPQ5675BQ5CQW9I
+AJgLOqzD8Q0qrXYi7HaEqzNx6p7RDTuhFgvTd+vS5d5+28Z5fm2umnq+GKHF8W5P
+ylp2Js119FTVO7brusAMKPe5emc7tC2ov8OFFemQvfHR41PLryap2VD81IOgmt/J
+kX/j/y5KGux5HZ3lxXqdJbKcAq4NKYQT0mCkRD4l6szaCEJ+k0SiM9DdTcBDefhR
+9q+pCOyMh7d8QjQ1075mF7T+PGkZQUW1DUjEfrZhICnKgq+iEoUmM0Ee5WtRqcnu
+5BTGQ2mSfc6rV+Vr+eYXqcg7Nxb3vFXYSTod1UhefonVqwdmyJ2sC79zp36Tbo2+
+65NW2WJK7KzPUyOJU0U9bcu0utvDOvGWmG+aHbymJgcoFzvZmlXqMXn97pSFn4jV
+y3SLRgJXOw1QLXL2Y5abcuoBVr4gCOxxk2vBeVxOMRXNqSWZOFIF1bu/PxuDA+Sa
+hEi44aHbPXt9opdssz/hdGfd8Wo7vEJrbg7c6zR6C/Akav1Rzy9oohIdgOw=
+-----END CERTIFICATE-----
+</ca>
+#key sample-keys/client.key
+<key>
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDsZY/pEsIaW+ZW
+KgipgjotRHijADuwn+cnEECT7/HMPqCqBKKAGxOp5v6B1nCQqNjU3jDYNQDSvmLw
+SNr8FY3Exm0LmfErgwAK0yojC+XN+TXfQ2EVcq2VmPZzIUFeoN1HJ6DVmtRBqBwd
+VyBxF4/3KJ4+B87s1Q5CTx50R45HndIUKCcsFBD10Za1k3SE7/kE3o1Kb993q+rR
+WNNE/loEAf8Gepf3/eNXSOHw30ATn2YjWuNVVD1UOe4A+RLx0t90LrrX8I3G3RhY
+HJMiC3X6qNbgtS8tudT+uU+G4nVIFmD7P8m0MEIp+zuzK7lZgWpG80WDv/3VGv83
+DG9b/WHxAgMBAAECggEBAIOdaCpUD02trOh8LqZxowJhBOl7z7/ex0uweMPk67LT
+i5AdVHwOlzwZJ8oSIknoOBEMRBWcLQEojt1JMuL2/R95emzjIKshHHzqZKNulFvB
+TIUpdnwChTKtH0mqUkLlPU3Ienty4IpNlpmfUKimfbkWHERdBJBHbtDsTABhdo3X
+9pCF/yRKqJS2Fy/Mkl3gv1y/NB1OL4Jhl7vQbf+kmgfQN2qdOVe2BOKQ8NlPUDmE
+/1XNIDaE3s6uvUaoFfwowzsCCwN2/8QrRMMKkjvV+lEVtNmQdYxj5Xj5IwS0vkK0
+6icsngW87cpZxxc1zsRWcSTloy5ohub4FgKhlolmigECgYEA+cBlxzLvaMzMlBQY
+kCac9KQMvVL+DIFHlZA5i5L/9pRVp4JJwj3GUoehFJoFhsxnKr8HZyLwBKlCmUVm
+VxnshRWiAU18emUmeAtSGawlAS3QXhikVZDdd/L20YusLT+DXV81wlKR97/r9+17
+klQOLkSdPm9wcMDOWMNHX8bUg8kCgYEA8k+hQv6+TR/+Beao2IIctFtw/EauaJiJ
+wW5ql1cpCLPMAOQUvjs0Km3zqctfBF8mUjdkcyJ4uhL9FZtfywY22EtRIXOJ/8VR
+we65mVo6RLR8YVM54sihanuFOnlyF9LIBWB+9pUfh1/Y7DSebh7W73uxhAxQhi3Y
+QwfIQIFd8OkCgYBalH4VXhLYhpaYCiXSej6ot6rrK2N6c5Tb2MAWMA1nh+r84tMP
+gMoh+pDgYPAqMI4mQbxUmqZEeoLuBe6VHpDav7rPECRaW781AJ4ZM4cEQ3Jz/inz
+4qOAMn10CF081/Ez9ykPPlU0bsYNWHNd4eB2xWnmUBKOwk7UgJatVPaUiQKBgQCI
+f18CVGpzG9CHFnaK8FCnMNOm6VIaTcNcGY0mD81nv5Dt943P054BQMsAHTY7SjZW
+HioRyZtkhonXAB2oSqnekh7zzxgv4sG5k3ct8evdBCcE1FNJc2eqikZ0uDETRoOy
+s7cRxNNr+QxDkyikM+80HOPU1PMPgwfOSrX90GJQ8QKBgEBKohGMV/sNa4t14Iau
+qO8aagoqh/68K9GFXljsl3/iCSa964HIEREtW09Qz1w3dotEgp2w8bsDa+OwWrLy
+0SY7T5jRViM3cDWRlUBLrGGiL0FiwsfqiRiji60y19erJgrgyGVIb1kIgIBRkgFM
+2MMweASzTmZcri4PA/5C0HYb
+-----END PRIVATE KEY-----
+</key>
+#cert sample-keys/client.crt
+<cert>
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 2 (0x2)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=KG, ST=NA, L=BISHKEK, O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ Validity
+ Not Before: Oct 22 21:59:53 2014 GMT
+ Not After : Oct 19 21:59:53 2024 GMT
+ Subject: C=KG, ST=NA, O=OpenVPN-TEST, CN=Test-Client/emailAddress=me@myhost.mydomain
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ec:65:8f:e9:12:c2:1a:5b:e6:56:2a:08:a9:82:
+ 3a:2d:44:78:a3:00:3b:b0:9f:e7:27:10:40:93:ef:
+ f1:cc:3e:a0:aa:04:a2:80:1b:13:a9:e6:fe:81:d6:
+ 70:90:a8:d8:d4:de:30:d8:35:00:d2:be:62:f0:48:
+ da:fc:15:8d:c4:c6:6d:0b:99:f1:2b:83:00:0a:d3:
+ 2a:23:0b:e5:cd:f9:35:df:43:61:15:72:ad:95:98:
+ f6:73:21:41:5e:a0:dd:47:27:a0:d5:9a:d4:41:a8:
+ 1c:1d:57:20:71:17:8f:f7:28:9e:3e:07:ce:ec:d5:
+ 0e:42:4f:1e:74:47:8e:47:9d:d2:14:28:27:2c:14:
+ 10:f5:d1:96:b5:93:74:84:ef:f9:04:de:8d:4a:6f:
+ df:77:ab:ea:d1:58:d3:44:fe:5a:04:01:ff:06:7a:
+ 97:f7:fd:e3:57:48:e1:f0:df:40:13:9f:66:23:5a:
+ e3:55:54:3d:54:39:ee:00:f9:12:f1:d2:df:74:2e:
+ ba:d7:f0:8d:c6:dd:18:58:1c:93:22:0b:75:fa:a8:
+ d6:e0:b5:2f:2d:b9:d4:fe:b9:4f:86:e2:75:48:16:
+ 60:fb:3f:c9:b4:30:42:29:fb:3b:b3:2b:b9:59:81:
+ 6a:46:f3:45:83:bf:fd:d5:1a:ff:37:0c:6f:5b:fd:
+ 61:f1
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ D2:B4:36:0F:B1:FC:DD:A5:EA:2A:F7:C7:23:89:FA:E3:FA:7A:44:1D
+ X509v3 Authority Key Identifier:
+ keyid:2B:40:E5:C9:7D:F5:F4:96:38:E9:2F:E3:2F:D9:40:64:C9:8E:05:9B
+ DirName:/C=KG/ST=NA/L=BISHKEK/O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ serial:A1:4E:DE:FA:90:F2:AE:81
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 7f:e0:fe:84:a7:ec:df:62:a5:cd:3c:c1:e6:42:b1:31:12:f0:
+ b9:da:a7:9e:3f:bd:96:52:b6:fc:55:74:64:3e:e4:ff:7e:aa:
+ f7:3e:06:18:5f:73:85:f8:c8:e0:67:1b:4d:97:ca:05:d0:37:
+ 07:33:64:9b:e6:78:77:14:9a:55:bb:2a:ac:c3:7f:c9:15:08:
+ 83:5c:c8:c2:61:d3:71:4c:05:0b:2b:cb:a3:87:6d:a0:32:ed:
+ b0:b3:27:97:4a:55:8d:01:2a:30:56:68:ab:f2:da:5c:10:73:
+ c9:aa:0a:9c:4b:4c:a0:5b:51:6e:0a:7e:6c:53:80:b0:00:e1:
+ 1e:9a:4c:0a:37:9e:20:89:bc:c5:e5:79:58:b7:45:ff:d3:c4:
+ a1:fd:d9:78:3d:45:16:74:df:82:44:1d:1d:81:50:5a:b9:32:
+ 4c:e2:4f:3f:0e:3a:65:5a:64:83:3b:29:31:c4:99:88:bc:c5:
+ 84:39:f2:19:12:e1:66:d0:ea:fb:75:b1:d2:27:be:91:59:a3:
+ 2b:09:d5:5c:bf:46:8e:d6:67:d6:0b:ec:da:ab:f0:80:19:87:
+ 64:07:a9:77:b1:5e:0c:e2:c5:1d:6a:ac:5d:23:f3:30:75:36:
+ 4e:ca:c3:4e:b0:4d:8c:2c:ce:52:61:63:de:d5:f5:ef:ef:0a:
+ 6b:23:25:26:3c:3a:f2:c3:c2:16:19:3f:a9:32:ba:68:f9:c9:
+ 12:3c:3e:c6:1f:ff:9b:4e:f4:90:b0:63:f5:d1:33:00:30:5a:
+ e8:24:fa:35:44:9b:6a:80:f3:a6:cc:7b:3c:73:5f:50:c4:30:
+ 71:d8:74:90:27:0a:01:4e:a5:5e:b1:f8:da:c2:61:81:11:ae:
+ 29:a3:8f:fa:7e:4c:4e:62:b1:00:de:92:e3:8f:6a:2e:da:d9:
+ 38:5d:6b:7c:0d:e4:01:aa:c8:c6:6d:8b:cd:c0:c8:6e:e4:57:
+ 21:8a:f6:46:30:d9:ad:51:a1:87:96:a6:53:c9:1e:c6:bb:c3:
+ eb:55:fe:8c:d6:5c:d5:c6:f3:ca:b0:60:d2:d4:2a:1f:88:94:
+ d3:4c:1a:da:0c:94:fe:c1:5d:0d:2a:db:99:29:5d:f6:dd:16:
+ c4:c8:4d:74:9e:80:d9:d0:aa:ed:7b:e3:30:e4:47:d8:f5:15:
+ c1:71:b8:c6:fd:ee:fc:9e:b2:5f:b5:b7:92:ed:ff:ca:37:f6:
+ c7:82:b4:54:13:9b:83:cd:87:8b:7e:64:f6:2e:54:3a:22:b1:
+ c5:c1:f4:a5:25:53:9a:4d:a8:0f:e7:35:4b:89:df:19:83:66:
+ 64:d9:db:d1:61:2b:24:1b:1d:44:44:fb:49:30:87:b7:49:23:
+ 08:02:8a:e0:25:f3:f4:43
+-----BEGIN CERTIFICATE-----
+MIIFFDCCAvygAwIBAgIBAjANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJLRzEL
+MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
+VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMB4XDTE0MTAy
+MjIxNTk1M1oXDTI0MTAxOTIxNTk1M1owajELMAkGA1UEBhMCS0cxCzAJBgNVBAgT
+Ak5BMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxFDASBgNVBAMTC1Rlc3QtQ2xpZW50
+MSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4wggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQDsZY/pEsIaW+ZWKgipgjotRHijADuwn+cnEECT
+7/HMPqCqBKKAGxOp5v6B1nCQqNjU3jDYNQDSvmLwSNr8FY3Exm0LmfErgwAK0yoj
+C+XN+TXfQ2EVcq2VmPZzIUFeoN1HJ6DVmtRBqBwdVyBxF4/3KJ4+B87s1Q5CTx50
+R45HndIUKCcsFBD10Za1k3SE7/kE3o1Kb993q+rRWNNE/loEAf8Gepf3/eNXSOHw
+30ATn2YjWuNVVD1UOe4A+RLx0t90LrrX8I3G3RhYHJMiC3X6qNbgtS8tudT+uU+G
+4nVIFmD7P8m0MEIp+zuzK7lZgWpG80WDv/3VGv83DG9b/WHxAgMBAAGjgcgwgcUw
+CQYDVR0TBAIwADAdBgNVHQ4EFgQU0rQ2D7H83aXqKvfHI4n64/p6RB0wgZgGA1Ud
+IwSBkDCBjYAUK0DlyX319JY46S/jL9lAZMmOBZuhaqRoMGYxCzAJBgNVBAYTAktH
+MQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UEChMMT3BlblZQ
+Ti1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW6CCQChTt76
+kPKugTANBgkqhkiG9w0BAQsFAAOCAgEAf+D+hKfs32KlzTzB5kKxMRLwudqnnj+9
+llK2/FV0ZD7k/36q9z4GGF9zhfjI4GcbTZfKBdA3BzNkm+Z4dxSaVbsqrMN/yRUI
+g1zIwmHTcUwFCyvLo4dtoDLtsLMnl0pVjQEqMFZoq/LaXBBzyaoKnEtMoFtRbgp+
+bFOAsADhHppMCjeeIIm8xeV5WLdF/9PEof3ZeD1FFnTfgkQdHYFQWrkyTOJPPw46
+ZVpkgzspMcSZiLzFhDnyGRLhZtDq+3Wx0ie+kVmjKwnVXL9GjtZn1gvs2qvwgBmH
+ZAepd7FeDOLFHWqsXSPzMHU2TsrDTrBNjCzOUmFj3tX17+8KayMlJjw68sPCFhk/
+qTK6aPnJEjw+xh//m070kLBj9dEzADBa6CT6NUSbaoDzpsx7PHNfUMQwcdh0kCcK
+AU6lXrH42sJhgRGuKaOP+n5MTmKxAN6S449qLtrZOF1rfA3kAarIxm2LzcDIbuRX
+IYr2RjDZrVGhh5amU8kexrvD61X+jNZc1cbzyrBg0tQqH4iU00wa2gyU/sFdDSrb
+mSld9t0WxMhNdJ6A2dCq7XvjMORH2PUVwXG4xv3u/J6yX7W3ku3/yjf2x4K0VBOb
+g82Hi35k9i5UOiKxxcH0pSVTmk2oD+c1S4nfGYNmZNnb0WErJBsdRET7STCHt0kj
+CAKK4CXz9EM=
+-----END CERTIFICATE-----
+</cert>
+#tls-auth sample-keys/ta.key 1
+key-direction 1
+<tls-auth>
+#
+# 2048 bit OpenVPN static key
+#
+-----BEGIN OpenVPN Static key V1-----
+a863b1cbdb911ff4ef3360ce135157e7
+241a465f5045f51cf9a92ebc24da34fd
+5fc48456778c977e374d55a8a7298aef
+40d0ab0c60b5e09838510526b73473a0
+8da46a8c352572dd86d4a871700a915b
+6aaa58a9dac560db2dfdd7ef15a202e1
+fca6913d7ee79c678c5798fbf7bd920c
+caa7a64720908da7254598b052d07f55
+5e31dc5721932cffbdd8965d04107415
+46c86823da18b66aab347e4522cc05ff
+634968889209c96b1024909cd4ce574c
+f829aa9c17d5df4a66043182ee23635d
+8cabf5a7ba02345ad94a3aa25a63d55c
+e13f4ad235a0825e3fe17f9419baff1c
+e73ad1dd652f1e48c7102fe8ee181e54
+10a160ae255f63fd01db1f29e6efcb8e
+-----END OpenVPN Static key V1-----
+</tls-auth>
+cipher AES-256-GCM
ping 1
inactive 120 10000000
diff --git a/sample/sample-config-files/loopback-server b/sample/sample-config-files/loopback-server
index 8e1f39c..58daeb5 100644
--- a/sample/sample-config-files/loopback-server
+++ b/sample/sample-config-files/loopback-server
@@ -22,5 +22,6 @@ ca sample-keys/ca.crt
key sample-keys/server.key
cert sample-keys/server.crt
tls-auth sample-keys/ta.key 0
+cipher AES-256-GCM
ping 1
inactive 120 10000000
diff --git a/sample/sample-config-files/server.conf b/sample/sample-config-files/server.conf
index 1dd477b..e702063 100644
--- a/sample/sample-config-files/server.conf
+++ b/sample/sample-config-files/server.conf
@@ -235,7 +235,7 @@ keepalive 10 120
# to help block DoS attacks and UDP port flooding.
#
# Generate with:
-# openvpn --genkey --secret ta.key
+# openvpn --genkey tls-auth ta.key
#
# The server and each client must have
# a copy of this key.
diff --git a/sample/sample-config-files/static-home.conf b/sample/sample-config-files/static-home.conf
deleted file mode 100644
index ed0c672..0000000
--- a/sample/sample-config-files/static-home.conf
+++ /dev/null
@@ -1,75 +0,0 @@
-#
-# Sample OpenVPN configuration file for
-# home using a pre-shared static key.
-#
-# '#' or ';' may be used to delimit comments.
-
-# Use a dynamic tun device.
-# For Linux 2.2 or non-Linux OSes,
-# you may want to use an explicit
-# unit number such as "tun1".
-# OpenVPN also supports virtual
-# ethernet "tap" devices.
-dev tun
-
-# Our OpenVPN peer is the office gateway.
-remote 1.2.3.4
-
-# 10.1.0.2 is our local VPN endpoint (home).
-# 10.1.0.1 is our remote VPN endpoint (office).
-ifconfig 10.1.0.2 10.1.0.1
-
-# Our up script will establish routes
-# once the VPN is alive.
-up ./home.up
-
-# Our pre-shared static key
-secret static.key
-
-# Cipher to use
-cipher AES-256-CBC
-
-# OpenVPN 2.0 uses UDP port 1194 by default
-# (official port assignment by iana.org 11/04).
-# OpenVPN 1.x uses UDP port 5000 by default.
-# Each OpenVPN tunnel must use
-# a different port number.
-# lport or rport can be used
-# to denote different ports
-# for local and remote.
-; port 1194
-
-# Downgrade UID and GID to
-# "nobody" after initialization
-# for extra security.
-; user nobody
-; group nobody
-
-# If you built OpenVPN with
-# LZO compression, uncomment
-# out the following line.
-; comp-lzo
-
-# Send a UDP ping to remote once
-# every 15 seconds to keep
-# stateful firewall connection
-# alive. Uncomment this
-# out if you are using a stateful
-# firewall.
-; ping 15
-
-# Uncomment this section for a more reliable detection when a system
-# loses its connection. For example, dial-ups or laptops that
-# travel to other locations.
-; ping 15
-; ping-restart 45
-; ping-timer-rem
-; persist-tun
-; persist-key
-
-# Verbosity level.
-# 0 -- quiet except for fatal errors.
-# 1 -- mostly quiet, but display non-fatal network errors.
-# 3 -- medium output, good for normal operation.
-# 9 -- verbose, good for troubleshooting
-verb 3
diff --git a/sample/sample-config-files/static-office.conf b/sample/sample-config-files/static-office.conf
deleted file mode 100644
index 609ddd0..0000000
--- a/sample/sample-config-files/static-office.conf
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# Sample OpenVPN configuration file for
-# office using a pre-shared static key.
-#
-# '#' or ';' may be used to delimit comments.
-
-# Use a dynamic tun device.
-# For Linux 2.2 or non-Linux OSes,
-# you may want to use an explicit
-# unit number such as "tun1".
-# OpenVPN also supports virtual
-# ethernet "tap" devices.
-dev tun
-
-# 10.1.0.1 is our local VPN endpoint (office).
-# 10.1.0.2 is our remote VPN endpoint (home).
-ifconfig 10.1.0.1 10.1.0.2
-
-# Our up script will establish routes
-# once the VPN is alive.
-up ./office.up
-
-# Our pre-shared static key
-secret static.key
-
-# Cipher to use
-cipher AES-256-CBC
-
-# OpenVPN 2.0 uses UDP port 1194 by default
-# (official port assignment by iana.org 11/04).
-# OpenVPN 1.x uses UDP port 5000 by default.
-# Each OpenVPN tunnel must use
-# a different port number.
-# lport or rport can be used
-# to denote different ports
-# for local and remote.
-; port 1194
-
-# Downgrade UID and GID to
-# "nobody" after initialization
-# for extra security.
-; user nobody
-; group nobody
-
-# If you built OpenVPN with
-# LZO compression, uncomment
-# out the following line.
-; comp-lzo
-
-# Send a UDP ping to remote once
-# every 15 seconds to keep
-# stateful firewall connection
-# alive. Uncomment this
-# out if you are using a stateful
-# firewall.
-; ping 15
-
-# Uncomment this section for a more reliable detection when a system
-# loses its connection. For example, dial-ups or laptops that
-# travel to other locations.
-; ping 15
-; ping-restart 45
-; ping-timer-rem
-; persist-tun
-; persist-key
-
-# Verbosity level.
-# 0 -- quiet except for fatal errors.
-# 1 -- mostly quiet, but display non-fatal network errors.
-# 3 -- medium output, good for normal operation.
-# 9 -- verbose, good for troubleshooting
-verb 3
diff --git a/sample/sample-config-files/tls-home.conf b/sample/sample-config-files/tls-home.conf
index daa4ea1..3a9297c 100644
--- a/sample/sample-config-files/tls-home.conf
+++ b/sample/sample-config-files/tls-home.conf
@@ -4,12 +4,9 @@
#
# '#' or ';' may be used to delimit comments.
-# Use a dynamic tun device.
-# For Linux 2.2 or non-Linux OSes,
-# you may want to use an explicit
-# unit number such as "tun1".
-# OpenVPN also supports virtual
-# ethernet "tap" devices.
+# Use a dynamic tun device. For non-Linux OSes, you may want to use an
+# explicit unit number such as "tun1".
+# OpenVPN also supports virtual ethernet "tap" devices.
dev tun
# Our OpenVPN peer is the office gateway.
@@ -37,6 +34,9 @@ cert home.crt
# Our private key
key home.key
+# Our data channel cipher (must match peer config)
+cipher AES-256-GCM
+
# OpenVPN 2.0 uses UDP port 1194 by default
# (official port assignment by iana.org 11/04).
# OpenVPN 1.x uses UDP port 5000 by default.
diff --git a/sample/sample-config-files/tls-office.conf b/sample/sample-config-files/tls-office.conf
index d196144..8105221 100644
--- a/sample/sample-config-files/tls-office.conf
+++ b/sample/sample-config-files/tls-office.conf
@@ -37,6 +37,9 @@ cert office.crt
# Our private key
key office.key
+# Our data channel cipher (must match peer config)
+cipher AES-256-GCM
+
# OpenVPN 2.0 uses UDP port 1194 by default
# (official port assignment by iana.org 11/04).
# OpenVPN 1.x uses UDP port 5000 by default.
diff --git a/sample/sample-keys/gen-sample-keys.sh b/sample/sample-keys/gen-sample-keys.sh
index 920513a..82f0880 100755
--- a/sample/sample-keys/gen-sample-keys.sh
+++ b/sample/sample-keys/gen-sample-keys.sh
@@ -3,7 +3,7 @@
# Run this script to set up a test CA, and test key-certificate pair for a
# server, and various clients.
#
-# Copyright (C) 2014 Steffan Karger <steffan@karger.me>
+# Copyright (C) 2014-2021 Steffan Karger <steffan@karger.me>
set -eu
command -v openssl >/dev/null 2>&1 || { echo >&2 "Unable to find openssl. Please make sure openssl is installed and in your path."; exit 1; }
@@ -15,7 +15,7 @@ then
fi
# Generate static key for tls-auth (or static key mode)
-$(dirname ${0})/../../src/openvpn/openvpn --genkey --secret ta.key
+$(dirname ${0})/../../src/openvpn/openvpn --genkey tls-auth ta.key
# Create required directories and files
mkdir -p sample-ca
diff --git a/sample/sample-keys/openssl.cnf b/sample/sample-keys/openssl.cnf
index aabfd48..02bf8ac 100644
--- a/sample/sample-keys/openssl.cnf
+++ b/sample/sample-keys/openssl.cnf
@@ -19,7 +19,7 @@ crl = $dir/crl.pem # The current CRL
private_key = $dir/ca.key # The private key
RANDFILE = $dir/.rand # private random number file
-x509_extensions = basic_exts # The extentions to add to the cert
+x509_extensions = basic_exts # The extensions to add to the cert
# This allows a V2 CRL. Ancient browsers don't like it, but anything Easy-RSA
# is designed for will. In return, we get the Issuer attached to CRLs.
@@ -54,7 +54,7 @@ default_bits = 2048
default_keyfile = privkey.pem
default_md = sha256
distinguished_name = cn_only
-x509_extensions = easyrsa_ca # The extentions to add to the self signed cert
+x509_extensions = easyrsa_ca # The extensions to add to the self signed cert
# A placeholder to handle the $EXTRA_EXTS feature:
#%EXTRA_EXTS% # Do NOT remove or change this line as $EXTRA_EXTS support requires it
diff --git a/sample/sample-plugins/Makefile b/sample/sample-plugins/Makefile
new file mode 100644
index 0000000..8646832
--- /dev/null
+++ b/sample/sample-plugins/Makefile
@@ -0,0 +1,585 @@
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
+# sample/sample-plugins/Makefile. Generated from Makefile.in by configure.
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+
+#
+# OpenVPN -- An application to securely tunnel IP networks
+# over a single UDP port, with support for SSL/TLS-based
+# session authentication and key exchange,
+# packet encryption, packet authentication, and
+# packet compression.
+#
+# Copyright (C) 2002-2021 OpenVPN Inc <sales@openvpn.net>
+#
+
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2020-2021 OpenVPN Inc <sales@openvpn.net>
+#
+
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/openvpn
+pkgincludedir = $(includedir)/openvpn
+pkglibdir = $(libdir)/openvpn
+pkglibexecdir = $(libexecdir)/openvpn
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = x86_64-pc-linux-gnu
+host_triplet = x86_64-pc-linux-gnu
+subdir = sample/sample-plugins
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
+ $(top_srcdir)/m4/ax_socklen_t.m4 \
+ $(top_srcdir)/m4/ax_varargs.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/version.m4 \
+ $(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_$(V))
+am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.plugins \
+ README
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = ${SHELL} /home/samuli/opt/openvpninc/openvpn-release-scripts/release/openvpn/missing aclocal-1.16
+AMTAR = $${TAR-tar}
+AM_DEFAULT_VERBOSITY = 1
+AR = ar
+AS = as
+AUTOCONF = ${SHELL} /home/samuli/opt/openvpninc/openvpn-release-scripts/release/openvpn/missing autoconf
+AUTOHEADER = ${SHELL} /home/samuli/opt/openvpninc/openvpn-release-scripts/release/openvpn/missing autoheader
+AUTOMAKE = ${SHELL} /home/samuli/opt/openvpninc/openvpn-release-scripts/release/openvpn/missing automake-1.16
+AWK = gawk
+CC = gcc
+CCDEPMODE = depmode=gcc3
+CFLAGS = -Wall -Wno-unused-parameter -Wno-unused-function -Wno-stringop-truncation -g -O2 -std=c99
+CMOCKA_CFLAGS =
+CMOCKA_LIBS =
+CPP = gcc -E
+CPPFLAGS =
+CYGPATH_W = echo
+DEFS = -DHAVE_CONFIG_H
+DEPDIR = .deps
+DLLTOOL = false
+DL_LIBS = -ldl
+DSYMUTIL =
+DUMPBIN =
+ECHO_C =
+ECHO_N = -n
+ECHO_T =
+EGREP = /usr/bin/grep -E
+ENABLE_UNITTESTS =
+EXEEXT =
+FGREP = /usr/bin/grep -F
+GIT = git
+GREP = /usr/bin/grep
+IFCONFIG = /usr/sbin/ifconfig
+INSTALL = /usr/bin/install -c
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_SCRIPT = ${INSTALL}
+INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
+IPROUTE = /usr/sbin/ip
+LD = /usr/bin/ld -m elf_x86_64
+LDFLAGS =
+LIBOBJS =
+LIBPAM_CFLAGS =
+LIBPAM_LIBS = -lpam
+LIBS =
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+LIPO =
+LN_S = ln -s
+LTLIBOBJS =
+LT_SYS_LIBRARY_PATH =
+LZ4_CFLAGS =
+LZ4_LIBS = -llz4
+LZO_CFLAGS =
+LZO_LIBS = -llzo2
+MAKEINFO = ${SHELL} /home/samuli/opt/openvpninc/openvpn-release-scripts/release/openvpn/missing makeinfo
+MANIFEST_TOOL = :
+MBEDTLS_CFLAGS =
+MBEDTLS_LIBS =
+MKDIR_P = /usr/bin/mkdir -p
+NETSTAT = netstat
+NM = /usr/bin/nm -B
+NMEDIT =
+OBJDUMP = objdump
+OBJEXT = o
+OPENSSL_CFLAGS =
+OPENSSL_LIBS = -lssl -lcrypto
+OPENVPN_VERSION_MAJOR = 2
+OPENVPN_VERSION_MINOR = 5
+OPENVPN_VERSION_PATCH = .4
+OPTIONAL_CRYPTO_CFLAGS =
+OPTIONAL_CRYPTO_LIBS = -lssl -lcrypto
+OPTIONAL_DL_LIBS = -ldl
+OPTIONAL_INOTIFY_CFLAGS =
+OPTIONAL_INOTIFY_LIBS =
+OPTIONAL_LZ4_CFLAGS =
+OPTIONAL_LZ4_LIBS = -llz4
+OPTIONAL_LZO_CFLAGS =
+OPTIONAL_LZO_LIBS = -llzo2
+OPTIONAL_PKCS11_HELPER_CFLAGS =
+OPTIONAL_PKCS11_HELPER_LIBS =
+OPTIONAL_SELINUX_LIBS =
+OPTIONAL_SYSTEMD_LIBS =
+OTOOL =
+OTOOL64 =
+P11KIT_CFLAGS =
+P11KIT_LIBS =
+PACKAGE = openvpn
+PACKAGE_BUGREPORT = openvpn-users@lists.sourceforge.net
+PACKAGE_NAME = OpenVPN
+PACKAGE_STRING = OpenVPN 2.5.4
+PACKAGE_TARNAME = openvpn
+PACKAGE_URL =
+PACKAGE_VERSION = 2.5.4
+PATH_SEPARATOR = :
+PKCS11_HELPER_CFLAGS =
+PKCS11_HELPER_LIBS = -lpthread -ldl -lcrypto -lpkcs11-helper
+PKG_CONFIG = /usr/bin/pkg-config
+PKG_CONFIG_LIBDIR =
+PKG_CONFIG_PATH =
+PLUGINDIR =
+PLUGIN_AUTH_PAM_CFLAGS =
+PLUGIN_AUTH_PAM_LIBS = -lpam
+RANLIB = ranlib
+RC =
+ROUTE = /usr/sbin/route
+RST2HTML = rst2html
+RST2MAN = rst2man
+SED = /usr/bin/sed
+SELINUX_LIBS = -lselinux
+SET_MAKE =
+SHELL = /bin/sh
+SOCKETS_LIBS = -lresolv
+STRIP = strip
+SYSTEMD_ASK_PASSWORD = /usr/bin/systemd-ask-password
+SYSTEMD_UNIT_DIR =
+TAP_CFLAGS =
+TAP_WIN_COMPONENT_ID = tap0901
+TAP_WIN_MIN_MAJOR = 9
+TAP_WIN_MIN_MINOR = 9
+TEST_CFLAGS = -I$(top_srcdir)/include
+TEST_LDFLAGS = -lssl -lcrypto -llzo2
+TMPFILES_DIR =
+VERSION = 2.5.4
+abs_builddir = /home/samuli/opt/openvpninc/openvpn-release-scripts/release/openvpn/sample/sample-plugins
+abs_srcdir = /home/samuli/opt/openvpninc/openvpn-release-scripts/release/openvpn/sample/sample-plugins
+abs_top_builddir = /home/samuli/opt/openvpninc/openvpn-release-scripts/release/openvpn
+abs_top_srcdir = /home/samuli/opt/openvpninc/openvpn-release-scripts/release/openvpn
+ac_ct_AR = ar
+ac_ct_CC = gcc
+ac_ct_DUMPBIN =
+am__include = include
+am__leading_dot = .
+am__quote =
+am__tar = $${TAR-tar} chof - "$$tardir"
+am__untar = $${TAR-tar} xf -
+bindir = ${exec_prefix}/bin
+build = x86_64-pc-linux-gnu
+build_alias =
+build_cpu = x86_64
+build_os = linux-gnu
+build_vendor = pc
+builddir = .
+datadir = ${datarootdir}
+datarootdir = ${prefix}/share
+docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
+dvidir = ${docdir}
+exec_prefix = ${prefix}
+host = x86_64-pc-linux-gnu
+host_alias =
+host_cpu = x86_64
+host_os = linux-gnu
+host_vendor = pc
+htmldir = ${docdir}
+includedir = ${prefix}/include
+infodir = ${datarootdir}/info
+install_sh = ${SHELL} /home/samuli/opt/openvpninc/openvpn-release-scripts/release/openvpn/install-sh
+libdir = ${exec_prefix}/lib
+libexecdir = ${exec_prefix}/libexec
+libsystemd_CFLAGS =
+libsystemd_LIBS =
+localedir = ${datarootdir}/locale
+localstatedir = ${prefix}/var
+mandir = ${datarootdir}/man
+mkdir_p = $(MKDIR_P)
+oldincludedir = /usr/include
+pdfdir = ${docdir}
+plugindir = ${libdir}/openvpn/plugins
+prefix = /usr/local
+program_transform_name = s,x,x,
+psdir = ${docdir}
+runstatedir = ${localstatedir}/run
+sampledir = $(docdir)/sample
+sbindir = ${exec_prefix}/sbin
+sharedstatedir = ${prefix}/com
+srcdir = .
+sysconfdir = ${prefix}/etc
+systemdunitdir =
+target_alias =
+tmpfilesdir =
+top_build_prefix = ../../
+top_builddir = ../..
+top_srcdir = ../..
+MAINTAINERCLEANFILES = \
+ $(srcdir)/Makefile.in
+
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir) \
+ -I$(top_srcdir)/include -I$(top_builddir)/include
+
+
+#
+# Plug-ins to build - listed entries should not carry any extensions
+#
+PLUGINS = \
+ defer/simple \
+ keying-material-exporter-demo/keyingmaterialexporter \
+ log/log log/log_v3 \
+ simple/base64 \
+ simple/simple \
+ client-connect/sample-client-connect
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/Makefile.plugins $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sample/sample-plugins/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign sample/sample-plugins/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+$(srcdir)/Makefile.plugins $(am__empty):
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ cscopelist-am ctags-am dist-hook distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# All the plugins to build - rewritten with .so extension
+all : $(foreach var, $(PLUGINS), $(var).so)
+
+# Do not automatically remove object files
+# This is a special Make setting, to avoid adding an implicit
+# 'rm' command on object files - due to the .c.o/%.so rules below
+.PRECIOUS: %.o
+
+# Compile step
+.c.o :
+ test -d `dirname $@` || $(MKDIR_P) `dirname $@`; \
+ $(CC) -c -o $@ $(CFLAGS) $(AM_CPPFLAGS) -fPIC $<
+
+# Link step
+%.so : %.o
+ $(CC) $(LDFLAGS) -shared -fPIC -o $@ $<
+
+# Clean up all build object and shared object files
+clean :
+ rm -f $(foreach var, $(PLUGINS), $(var).o) \
+ $(foreach var, $(PLUGINS), $(var).so)
+
+# We don't want automake to pull in libtool for building these
+# sample-plugins. Even though this breaks the conceptual ideas
+# around autoconf/automake/libtools ... these sample plug-ins
+# are just sample code, not to be installed or distributed outside
+# of the source tarball. Not even built by default, by design.
+#
+# We only add this as a simple and convenient way to build all
+# these plug-ins with the same build parameters as the rest
+# of the OpenVPN code.
+#
+# All the plugins which will be built are processed in this
+# separate Makefile, which disconnects everything just enough
+# to achieve our goal.
+
+dist-hook :
+ make -f Makefile.plugins clean
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/sample/sample-plugins/Makefile.am b/sample/sample-plugins/Makefile.am
new file mode 100644
index 0000000..9539d05
--- /dev/null
+++ b/sample/sample-plugins/Makefile.am
@@ -0,0 +1,34 @@
+#
+# OpenVPN -- An application to securely tunnel IP networks
+# over a single UDP port, with support for SSL/TLS-based
+# session authentication and key exchange,
+# packet encryption, packet authentication, and
+# packet compression.
+#
+# Copyright (C) 2002-2021 OpenVPN Inc <sales@openvpn.net>
+#
+
+MAINTAINERCLEANFILES = \
+ $(srcdir)/Makefile.in
+
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir) \
+ -I$(top_srcdir)/include -I$(top_builddir)/include
+
+# We don't want automake to pull in libtool for building these
+# sample-plugins. Even though this breaks the conceptual ideas
+# around autoconf/automake/libtools ... these sample plug-ins
+# are just sample code, not to be installed or distributed outside
+# of the source tarball. Not even built by default, by design.
+#
+# We only add this as a simple and convenient way to build all
+# these plug-ins with the same build parameters as the rest
+# of the OpenVPN code.
+#
+# All the plugins which will be built are processed in this
+# separate Makefile, which disconnects everything just enough
+# to achieve our goal.
+include Makefile.plugins
+
+
+dist-hook :
+ make -f Makefile.plugins clean
diff --git a/sample/sample-plugins/Makefile.in b/sample/sample-plugins/Makefile.in
new file mode 100644
index 0000000..8be23e0
--- /dev/null
+++ b/sample/sample-plugins/Makefile.in
@@ -0,0 +1,585 @@
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# OpenVPN -- An application to securely tunnel IP networks
+# over a single UDP port, with support for SSL/TLS-based
+# session authentication and key exchange,
+# packet encryption, packet authentication, and
+# packet compression.
+#
+# Copyright (C) 2002-2021 OpenVPN Inc <sales@openvpn.net>
+#
+
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2020-2021 OpenVPN Inc <sales@openvpn.net>
+#
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = sample/sample-plugins
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
+ $(top_srcdir)/m4/ax_socklen_t.m4 \
+ $(top_srcdir)/m4/ax_varargs.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/version.m4 \
+ $(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.plugins \
+ README
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMOCKA_CFLAGS = @CMOCKA_CFLAGS@
+CMOCKA_LIBS = @CMOCKA_LIBS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_UNITTESTS = @ENABLE_UNITTESTS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GIT = @GIT@
+GREP = @GREP@
+IFCONFIG = @IFCONFIG@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPROUTE = @IPROUTE@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBPAM_CFLAGS = @LIBPAM_CFLAGS@
+LIBPAM_LIBS = @LIBPAM_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+LZO_CFLAGS = @LZO_CFLAGS@
+LZO_LIBS = @LZO_LIBS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
+MKDIR_P = @MKDIR_P@
+NETSTAT = @NETSTAT@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
+OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
+OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
+OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_INOTIFY_CFLAGS = @OPTIONAL_INOTIFY_CFLAGS@
+OPTIONAL_INOTIFY_LIBS = @OPTIONAL_INOTIFY_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
+OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
+OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
+OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
+OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@
+OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@
+OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+P11KIT_CFLAGS = @P11KIT_CFLAGS@
+P11KIT_LIBS = @P11KIT_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKCS11_HELPER_CFLAGS = @PKCS11_HELPER_CFLAGS@
+PKCS11_HELPER_LIBS = @PKCS11_HELPER_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGINDIR = @PLUGINDIR@
+PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
+PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+ROUTE = @ROUTE@
+RST2HTML = @RST2HTML@
+RST2MAN = @RST2MAN@
+SED = @SED@
+SELINUX_LIBS = @SELINUX_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKETS_LIBS = @SOCKETS_LIBS@
+STRIP = @STRIP@
+SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@
+SYSTEMD_UNIT_DIR = @SYSTEMD_UNIT_DIR@
+TAP_CFLAGS = @TAP_CFLAGS@
+TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
+TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
+TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+TMPFILES_DIR = @TMPFILES_DIR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sampledir = @sampledir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+tmpfilesdir = @tmpfilesdir@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = \
+ $(srcdir)/Makefile.in
+
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir) \
+ -I$(top_srcdir)/include -I$(top_builddir)/include
+
+
+#
+# Plug-ins to build - listed entries should not carry any extensions
+#
+PLUGINS = \
+ defer/simple \
+ keying-material-exporter-demo/keyingmaterialexporter \
+ log/log log/log_v3 \
+ simple/base64 \
+ simple/simple \
+ client-connect/sample-client-connect
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/Makefile.plugins $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sample/sample-plugins/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign sample/sample-plugins/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+$(srcdir)/Makefile.plugins $(am__empty):
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ cscopelist-am ctags-am dist-hook distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# All the plugins to build - rewritten with .so extension
+all : $(foreach var, $(PLUGINS), $(var).so)
+
+# Do not automatically remove object files
+# This is a special Make setting, to avoid adding an implicit
+# 'rm' command on object files - due to the .c.o/%.so rules below
+.PRECIOUS: %.o
+
+# Compile step
+.c.o :
+ test -d `dirname $@` || $(MKDIR_P) `dirname $@`; \
+ $(CC) -c -o $@ $(CFLAGS) $(AM_CPPFLAGS) -fPIC $<
+
+# Link step
+%.so : %.o
+ $(CC) $(LDFLAGS) -shared -fPIC -o $@ $<
+
+# Clean up all build object and shared object files
+clean :
+ rm -f $(foreach var, $(PLUGINS), $(var).o) \
+ $(foreach var, $(PLUGINS), $(var).so)
+
+# We don't want automake to pull in libtool for building these
+# sample-plugins. Even though this breaks the conceptual ideas
+# around autoconf/automake/libtools ... these sample plug-ins
+# are just sample code, not to be installed or distributed outside
+# of the source tarball. Not even built by default, by design.
+#
+# We only add this as a simple and convenient way to build all
+# these plug-ins with the same build parameters as the rest
+# of the OpenVPN code.
+#
+# All the plugins which will be built are processed in this
+# separate Makefile, which disconnects everything just enough
+# to achieve our goal.
+
+dist-hook :
+ make -f Makefile.plugins clean
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/sample/sample-plugins/Makefile.plugins b/sample/sample-plugins/Makefile.plugins
new file mode 100644
index 0000000..44c9cea
--- /dev/null
+++ b/sample/sample-plugins/Makefile.plugins
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2020-2021 OpenVPN Inc <sales@openvpn.net>
+#
+
+#
+# Plug-ins to build - listed entries should not carry any extensions
+#
+PLUGINS = \
+ defer/simple \
+ keying-material-exporter-demo/keyingmaterialexporter \
+ log/log log/log_v3 \
+ simple/base64 \
+ simple/simple \
+ client-connect/sample-client-connect
+
+# All the plugins to build - rewritten with .so extension
+all : $(foreach var, $(PLUGINS), $(var).so)
+
+# Do not automatically remove object files
+# This is a special Make setting, to avoid adding an implicit
+# 'rm' command on object files - due to the .c.o/%.so rules below
+.PRECIOUS: %.o
+
+# Compile step
+.c.o :
+ test -d `dirname $@` || $(MKDIR_P) `dirname $@`; \
+ $(CC) -c -o $@ $(CFLAGS) $(AM_CPPFLAGS) -fPIC $<
+
+# Link step
+%.so : %.o
+ $(CC) $(LDFLAGS) -shared -fPIC -o $@ $<
+
+# Clean up all build object and shared object files
+clean :
+ rm -f $(foreach var, $(PLUGINS), $(var).o) \
+ $(foreach var, $(PLUGINS), $(var).so)
diff --git a/sample/sample-plugins/README b/sample/sample-plugins/README
new file mode 100644
index 0000000..cf1b355
--- /dev/null
+++ b/sample/sample-plugins/README
@@ -0,0 +1,43 @@
+OpenVPN plug-in examples.
+
+Examples provided:
+
+* authentication and logging
+simple/simple.c -- using the --auth-user-pass-verify callback, verify
+ that the username/password is "foo"/"bar".
+defer/simple.c -- using the --auth-user-pass-verify callback,
+ test deferred authentication.
+log/log.c -- Extended variant of simple/simple.c which adds more
+ logging of what is happening inside the plug-in
+log/log_v3.c -- A variant of log/log.c, which makes use of the
+ OpenVPN plug-in v3 API. This will also log even more
+ information related to certificates in use.
+
+* client-connect (and logging)
+client-connect/sample-client-connect -- demonstrate how to use the
+ CLIENT_CONNECT and CLIENT_CONNECT_V2 hooks to achieve
+ "per client configuration / logging / ..." actions,
+ both in synchronous and async/deferred mode
+
+* cryptography related
+simple/base64.c -- Example using the OpenVPN exported base64 encode/decode
+ functions
+keying-material-exporter-demo/keyingmaterialexporter.c
+ -- Example based on TLS Keying Material Exporters over HTTP [RFC-5705]
+ (openvpn/doc/keying-material-exporter.txt). For more details, see
+ keying-material-exporter-demo/README
+
+
+To build on *BSD/Linux platforms (requires GNU Make):
+
+ gmake (builds a default set of plug-ins)
+ gmake simple/simple.so
+
+To build on Windows platform (MinGW):
+
+ cd simple; ./winbuild simple.so
+
+To use in OpenVPN, add to config file:
+
+ plugin simple.so (Linux/BSD/etc.)
+ plugin simple.dll
diff --git a/sample/sample-plugins/client-connect/README b/sample/sample-plugins/client-connect/README
new file mode 100644
index 0000000..cb3e0f3
--- /dev/null
+++ b/sample/sample-plugins/client-connect/README
@@ -0,0 +1,38 @@
+OpenVPN plugin examples.
+
+Examples provided:
+
+sample-client-connect.c
+
+ - hook to all plugin hooks that openvpn offers
+ - log which hook got called
+ - on CLIENT_CONNECT or CLIENT_CONNECT_V2 set some config variables
+ (controlled by "setenv plugin_cc_config ..." and "plugin_cc2_config"
+ in openvpn's config)
+
+ - if the environment variable UV_WANT_CC_FAIL is set, fail
+ - if the environment variable UV_WANT_CC_DISABLE is set, reject ("disable")
+ - if the environment variable UV_WANT_CC_ASYNC is set, go to
+ asynchronous/deferred mode on CLIENT_CONNECT, and sleep for
+ ${UV_WANT_CC_ASYNC} seconds
+
+ - if the environment variable UV_WANT_CC2_FAIL is set, fail CC2
+ - if the environment variable UV_WANT_CC2_DISABLE is set, reject ("disable")
+ - if the environment variable UV_WANT_CC2_ASYNC is set, go to
+ asynchronous/deferred mode on CLIENT_CONNECT_V2, and sleep for
+ ${UV_WANT_CC2_ASYNC} seconds
+
+ (this can be client-controlled with --setenv UV_WANT_CC_ASYNC nnn
+ etc. --> for easy testing server code paths)
+
+To build for unixy platforms (not very sophisticated right now, needs gmake):
+
+ .../sample-plugins$ gmake client-connect/sample-client-connect.so
+
+(This plugin has not been tested on Windows, and might not even work due
+to its use of fork() and wait(). Let us know if it does or needs patches)
+
+
+To use in OpenVPN, add to config file:
+
+ plugin sample-client-connect.so (Linux/BSD/etc.)
diff --git a/sample/sample-plugins/client-connect/sample-client-connect.c b/sample/sample-plugins/client-connect/sample-client-connect.c
new file mode 100644
index 0000000..cc85aeb
--- /dev/null
+++ b/sample/sample-plugins/client-connect/sample-client-connect.c
@@ -0,0 +1,612 @@
+/*
+ * 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) 2002-2021 OpenVPN Inc <sales@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; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * This file implements a simple OpenVPN plugin module which
+ * will log the calls made, and send back some config statements
+ * when called on the CLIENT_CONNECT and CLIENT_CONNECT_V2 hooks.
+ *
+ * it can be asked to fail or go to async/deferred mode by setting
+ * environment variables (UV_WANT_CC_FAIL, UV_WANT_CC_ASYNC,
+ * UV_WANT_CC2_ASYNC) - mostly used as a testing vehicle for the
+ * server side code to handle these cases
+ *
+ * See the README file for build instructions and env control variables.
+ */
+
+/* strdup() might need special defines to be visible in <string.h> */
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+
+#include "openvpn-plugin.h"
+
+/* Pointers to functions exported from openvpn */
+static plugin_log_t plugin_log = NULL;
+static plugin_secure_memzero_t plugin_secure_memzero = NULL;
+static plugin_base64_decode_t plugin_base64_decode = NULL;
+
+/* module name for plugin_log() */
+static char *MODULE = "sample-cc";
+
+/*
+ * Our context, where we keep our state.
+ */
+
+struct plugin_context {
+ int verb; /* logging verbosity */
+};
+
+/* this is used for the CLIENT_CONNECT_V2 async/deferred handler
+ *
+ * the "CLIENT_CONNECT_V2" handler puts per-client information into
+ * this, and the "CLIENT_CONNECT_DEFER_V2" handler looks at it to see
+ * if it's time yet to succeed/fail
+ */
+struct plugin_per_client_context {
+ time_t sleep_until; /* wakeup time (time() + sleep) */
+ bool want_fail;
+ bool want_disable;
+ const char *client_config;
+};
+
+/*
+ * Given an environmental variable name, search
+ * the envp array for its value, returning it
+ * if found or NULL otherwise.
+ */
+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;
+}
+
+
+static int
+atoi_null0(const char *str)
+{
+ if (str)
+ {
+ return atoi(str);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/* use v3 functions so we can use openvpn's logging and base64 etc. */
+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)
+{
+ /* const char **argv = args->argv; */ /* command line arguments (unused) */
+ const char **envp = args->envp; /* environment variables */
+
+ /* Check API compatibility -- struct version 5 or higher needed */
+ if (v3structver < 5)
+ {
+ fprintf(stderr, "sample-client-connect: this plugin is incompatible with the running version of OpenVPN\n");
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
+ /*
+ * Allocate our context
+ */
+ struct plugin_context *context = calloc(1, sizeof(struct plugin_context));
+ if (!context)
+ {
+ goto error;
+ }
+
+ /*
+ * Intercept just about everything...
+ */
+ ret->type_mask =
+ OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_UP)
+ |OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_DOWN)
+ |OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_ROUTE_UP)
+ |OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_IPCHANGE)
+ |OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_TLS_VERIFY)
+ |OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_CONNECT)
+ |OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_CONNECT_V2)
+ |OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_CONNECT_DEFER_V2)
+ |OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_DISCONNECT)
+ |OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_LEARN_ADDRESS)
+ |OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_TLS_FINAL);
+
+ /* Save global pointers to functions exported from openvpn */
+ plugin_log = args->callbacks->plugin_log;
+ plugin_secure_memzero = args->callbacks->plugin_secure_memzero;
+ plugin_base64_decode = args->callbacks->plugin_base64_decode;
+
+ /*
+ * Get verbosity level from environment
+ */
+ context->verb = atoi_null0(get_env("verb", envp));
+
+ ret->handle = (openvpn_plugin_handle_t *) context;
+ plugin_log(PLOG_NOTE, MODULE, "initialization succeeded");
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+
+error:
+ if (context)
+ {
+ free(context);
+ }
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+}
+
+
+/* there are two possible interfaces for an openvpn plugin how
+ * to be called on "client connect", which primarily differ in the
+ * way config options are handed back to the client instance
+ * (see openvpn/multi.c, multi_client_connect_call_plugin_{v1,v2}())
+ *
+ * OPENVPN_PLUGIN_CLIENT_CONNECT
+ * openvpn creates a temp file and passes the name to the plugin
+ * (via argv[1] variable, argv[0] is the name of the plugin)
+ * the plugin can write config statements to that file, and openvpn
+ * reads it in like a "ccd/$cn" per-client config file
+ *
+ * OPENVPN_PLUGIN_CLIENT_CONNECT_V2
+ * the caller passes in a pointer to an "openvpn_plugin_string_list"
+ * (openvpn-plugin.h), which is a linked list of (name,value) pairs
+ *
+ * we fill in one node with name="config" and value="our config"
+ *
+ * both "l" and "l->name" and "l->value" are malloc()ed by the plugin
+ * and free()ed by the caller (openvpn_plugin_string_list_free())
+ */
+
+/* helper function to write actual "here are your options" file,
+ * called from sync and sync handler
+ */
+int
+write_cc_options_file(const char *name, const char **envp)
+{
+ if (!name)
+ {
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+ }
+
+ FILE *fp = fopen(name,"w");
+ if (!fp)
+ {
+ plugin_log(PLOG_ERR, MODULE, "fopen('%s') failed", name);
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
+ /* config to-be-sent can come from "setenv plugin_cc_config" in openvpn */
+ const char *p = get_env("plugin_cc_config", envp);
+ if (p)
+ {
+ fprintf(fp, "%s\n", p);
+ }
+
+ /* some generic config snippets so we know it worked */
+ fprintf(fp, "push \"echo sample-cc plugin 1 called\"\n");
+
+ /* if the caller wants, reject client by means of "disable" option */
+ if (get_env("UV_WANT_CC_DISABLE", envp))
+ {
+ plugin_log(PLOG_NOTE, MODULE, "env has UV_WANT_CC_DISABLE, reject");
+ fprintf(fp, "disable\n");
+ }
+ fclose(fp);
+
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+}
+
+int
+cc_handle_deferred_v1(int seconds, const char *name, const char **envp)
+{
+ const char *ccd_file = get_env("client_connect_deferred_file", envp);
+ if (!ccd_file)
+ {
+ plugin_log(PLOG_NOTE, MODULE, "env has UV_WANT_CC_ASYNC=%d, but "
+ "'client_connect_deferred_file' not set -> fail", seconds);
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
+ /* the CLIENT_CONNECT (v1) API is a bit tricky to work with, because
+ * completition can be signalled both by the "deferred_file" and by
+ * the new ...CLIENT_CONNECT_DEFER API - which is optional.
+ *
+ * For OpenVPN to be able to differenciate, we must create the file
+ * right away if we want to use that for signalling.
+ */
+ int fd = open(ccd_file, O_WRONLY);
+ if (fd < 0)
+ {
+ plugin_log(PLOG_ERR|PLOG_ERRNO, MODULE, "open('%s') failed", ccd_file);
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
+ if (write(fd, "2", 1) != 1)
+ {
+ plugin_log(PLOG_ERR|PLOG_ERRNO, MODULE, "write to '%s' failed", ccd_file );
+ close(fd);
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+ close(fd);
+
+ /* we do not want to complicate our lives with having to wait()
+ * for child processes (so they are not zombiefied) *and* we MUST NOT
+ * fiddle with signal handlers (= shared with openvpn main), so
+ * we use double-fork() trick.
+ */
+
+ /* fork, sleep, succeed/fail according to env vars */
+ pid_t p1 = fork();
+ if (p1 < 0) /* Fork failed */
+ {
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+ if (p1 > 0) /* parent process */
+ {
+ waitpid(p1, NULL, 0);
+ return OPENVPN_PLUGIN_FUNC_DEFERRED;
+ }
+
+ /* first gen child process, fork() again and exit() right away */
+ pid_t p2 = fork();
+ if (p2 < 0)
+ {
+ plugin_log(PLOG_ERR|PLOG_ERRNO, MODULE, "BACKGROUND: fork(2) failed");
+ exit(1);
+ }
+ if (p2 > 0) /* new parent: exit right away */
+ {
+ exit(0);
+ }
+
+ /* (grand-)child process
+ * - never call "return" now (would mess up openvpn)
+ * - return status is communicated by file
+ * - then exit()
+ */
+
+ /* do mighty complicated work that will really take time here... */
+ plugin_log(PLOG_NOTE, MODULE, "in async/deferred handler, sleep(%d)", seconds);
+ sleep(seconds);
+
+ /* write config options to openvpn */
+ int ret = write_cc_options_file(name, envp);
+
+ /* by setting "UV_WANT_CC_FAIL" we can be triggered to fail */
+ const char *p = get_env("UV_WANT_CC_FAIL", envp);
+ if (p)
+ {
+ plugin_log(PLOG_NOTE, MODULE, "env has UV_WANT_CC_FAIL=%s -> fail", p);
+ ret = OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
+ /* now signal success/failure state to openvpn */
+ fd = open(ccd_file, O_WRONLY);
+ if (fd < 0)
+ {
+ plugin_log(PLOG_ERR|PLOG_ERRNO, MODULE, "open('%s') failed", ccd_file);
+ exit(1);
+ }
+
+ plugin_log(PLOG_NOTE, MODULE, "cc_handle_deferred_v1: done, signalling %s",
+ (ret == OPENVPN_PLUGIN_FUNC_SUCCESS) ? "success" : "fail" );
+
+ if (write(fd, (ret == OPENVPN_PLUGIN_FUNC_SUCCESS) ? "1" : "0", 1) != 1)
+ {
+ plugin_log(PLOG_ERR|PLOG_ERRNO, MODULE, "write to '%s' failed", ccd_file );
+ }
+ close(fd);
+
+ exit(0);
+}
+
+int
+openvpn_plugin_client_connect(struct plugin_context *context,
+ const char **argv,
+ const char **envp)
+{
+ /* log environment variables handed to us by OpenVPN, but
+ * only if "setenv verb" is 3 or higher (arbitrary number)
+ */
+ if (context->verb>=3)
+ {
+ for (int i = 0; argv[i]; i++)
+ {
+ plugin_log(PLOG_NOTE, MODULE, "per-client argv: %s", argv[i]);
+ }
+ for (int i = 0; envp[i]; i++)
+ {
+ plugin_log(PLOG_NOTE, MODULE, "per-client env: %s", envp[i]);
+ }
+ }
+
+ /* by setting "UV_WANT_CC_ASYNC" we go to async/deferred mode */
+ const char *p = get_env("UV_WANT_CC_ASYNC", envp);
+ if (p)
+ {
+ /* the return value will usually be OPENVPN_PLUGIN_FUNC_DEFERRED
+ * ("I will do my job in the background, check the status file!")
+ * but depending on env setup it might be "..._ERRROR"
+ */
+ return cc_handle_deferred_v1(atoi(p), argv[1], envp);
+ }
+
+ /* -- this is synchronous mode (openvpn waits for us) -- */
+
+ /* by setting "UV_WANT_CC_FAIL" we can be triggered to fail */
+ p = get_env("UV_WANT_CC_FAIL", envp);
+ if (p)
+ {
+ plugin_log(PLOG_NOTE, MODULE, "env has UV_WANT_CC_FAIL=%s -> fail", p);
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
+ /* does the caller want options? give them some */
+ int ret = write_cc_options_file(argv[1], envp);
+
+ return ret;
+}
+
+int
+openvpn_plugin_client_connect_v2(struct plugin_context *context,
+ struct plugin_per_client_context *pcc,
+ const char **envp,
+ struct openvpn_plugin_string_list **return_list)
+{
+ /* by setting "UV_WANT_CC2_ASYNC" we go to async/deferred mode */
+ const char *want_async = get_env("UV_WANT_CC2_ASYNC", envp);
+ const char *want_fail = get_env("UV_WANT_CC2_FAIL", envp);
+ const char *want_disable = get_env("UV_WANT_CC2_DISABLE", envp);
+
+ /* config to push towards client - can be controlled by OpenVPN
+ * config ("setenv plugin_cc2_config ...") - mostly useful in a
+ * regression test environment to push stuff like routes which are
+ * then verified by t_client ping tests
+ */
+ const char *client_config = get_env("plugin_cc2_config", envp);
+ if (!client_config)
+ {
+ /* pick something meaningless which can be verified in client log */
+ client_config = "push \"setenv CC2 MOOH\"\n";
+ }
+
+ if (want_async)
+ {
+ /* we do no really useful work here, so we just tell the
+ * "CLIENT_CONNECT_DEFER_V2" handler that it should sleep
+ * and then "do things" via the per-client-context
+ */
+ pcc->sleep_until = time(NULL) + atoi(want_async);
+ pcc->want_fail = (want_fail != NULL);
+ pcc->want_disable = (want_disable != NULL);
+ pcc->client_config = client_config;
+ plugin_log(PLOG_NOTE, MODULE, "env has UV_WANT_CC2_ASYNC=%s -> set up deferred handler", want_async);
+ return OPENVPN_PLUGIN_FUNC_DEFERRED;
+ }
+
+ /* by setting "UV_WANT_CC2_FAIL" we can be triggered to fail here */
+ if (want_fail)
+ {
+ plugin_log(PLOG_NOTE, MODULE, "env has UV_WANT_CC2_FAIL=%s -> fail", want_fail);
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
+ struct openvpn_plugin_string_list *rl =
+ calloc(1, sizeof(struct openvpn_plugin_string_list));
+ if (!rl)
+ {
+ plugin_log(PLOG_ERR, MODULE, "malloc(return_list) failed");
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+ rl->name = strdup("config");
+ if (want_disable)
+ {
+ plugin_log(PLOG_NOTE, MODULE, "env has UV_WANT_CC2_DISABLE, reject");
+ rl->value = strdup("disable\n");
+ }
+ else
+ {
+ rl->value = strdup(client_config);
+ }
+
+ if (!rl->name || !rl->value)
+ {
+ plugin_log(PLOG_ERR, MODULE, "malloc(return_list->xx) failed");
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
+ *return_list = rl;
+
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+}
+
+int
+openvpn_plugin_client_connect_defer_v2(struct plugin_context *context,
+ struct plugin_per_client_context *pcc,
+ struct openvpn_plugin_string_list
+ **return_list)
+{
+ time_t time_left = pcc->sleep_until - time(NULL);
+ plugin_log(PLOG_NOTE, MODULE, "defer_v2: seconds left=%d",
+ (int) time_left);
+
+ /* not yet due? */
+ if (time_left > 0)
+ {
+ return OPENVPN_PLUGIN_FUNC_DEFERRED;
+ }
+
+ /* client wants fail? */
+ if (pcc->want_fail)
+ {
+ plugin_log(PLOG_NOTE, MODULE, "env has UV_WANT_CC2_FAIL -> fail" );
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
+ /* fill in RL according to with-disable / without-disable */
+
+ /* TODO: unify this with non-deferred case */
+ struct openvpn_plugin_string_list *rl =
+ calloc(1, sizeof(struct openvpn_plugin_string_list));
+ if (!rl)
+ {
+ plugin_log(PLOG_ERR, MODULE, "malloc(return_list) failed");
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+ rl->name = strdup("config");
+ if (pcc->want_disable)
+ {
+ plugin_log(PLOG_NOTE, MODULE, "env has UV_WANT_CC2_DISABLE, reject");
+ rl->value = strdup("disable\n");
+ }
+ else
+ {
+ rl->value = strdup(pcc->client_config);
+ }
+
+ if (!rl->name || !rl->value)
+ {
+ plugin_log(PLOG_ERR, MODULE, "malloc(return_list->xx) failed");
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
+ *return_list = rl;
+
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+}
+
+OPENVPN_EXPORT int
+openvpn_plugin_func_v2(openvpn_plugin_handle_t handle,
+ const int type,
+ const char *argv[],
+ const char *envp[],
+ void *per_client_context,
+ struct openvpn_plugin_string_list **return_list)
+{
+ struct plugin_context *context = (struct plugin_context *) handle;
+ struct plugin_per_client_context *pcc = (struct plugin_per_client_context *) per_client_context;
+
+ /* for most functions, we just "don't do anything" but log the
+ * event received (so one can follow it in the log and understand
+ * the sequence of events). CONNECT and CONNECT_V2 are handled
+ */
+ switch (type)
+ {
+ case OPENVPN_PLUGIN_UP:
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_UP");
+ break;
+
+ case OPENVPN_PLUGIN_DOWN:
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_DOWN");
+ break;
+
+ case OPENVPN_PLUGIN_ROUTE_UP:
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_ROUTE_UP");
+ break;
+
+ case OPENVPN_PLUGIN_IPCHANGE:
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_IPCHANGE");
+ break;
+
+ case OPENVPN_PLUGIN_TLS_VERIFY:
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_TLS_VERIFY");
+ break;
+
+ case OPENVPN_PLUGIN_CLIENT_CONNECT:
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_CLIENT_CONNECT");
+ return openvpn_plugin_client_connect(context, argv, envp);
+
+ case OPENVPN_PLUGIN_CLIENT_CONNECT_V2:
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_CLIENT_CONNECT_V2");
+ return openvpn_plugin_client_connect_v2(context, pcc, envp,
+ return_list);
+
+ case OPENVPN_PLUGIN_CLIENT_CONNECT_DEFER_V2:
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_CLIENT_CONNECT_DEFER_V2");
+ return openvpn_plugin_client_connect_defer_v2(context, pcc,
+ return_list);
+
+ case OPENVPN_PLUGIN_CLIENT_DISCONNECT:
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_CLIENT_DISCONNECT");
+ break;
+
+ case OPENVPN_PLUGIN_LEARN_ADDRESS:
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_LEARN_ADDRESS");
+ break;
+
+ case OPENVPN_PLUGIN_TLS_FINAL:
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_TLS_FINAL");
+ break;
+
+ default:
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_? type=%d\n", type);
+ }
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+}
+
+OPENVPN_EXPORT void *
+openvpn_plugin_client_constructor_v1(openvpn_plugin_handle_t handle)
+{
+ printf("FUNC: openvpn_plugin_client_constructor_v1\n");
+ return calloc(1, sizeof(struct plugin_per_client_context));
+}
+
+OPENVPN_EXPORT void
+openvpn_plugin_client_destructor_v1(openvpn_plugin_handle_t handle, void *per_client_context)
+{
+ printf("FUNC: openvpn_plugin_client_destructor_v1\n");
+ free(per_client_context);
+}
+
+OPENVPN_EXPORT void
+openvpn_plugin_close_v1(openvpn_plugin_handle_t handle)
+{
+ struct plugin_context *context = (struct plugin_context *) handle;
+ printf("FUNC: openvpn_plugin_close_v1\n");
+ free(context);
+}
diff --git a/sample/sample-plugins/defer/README b/sample/sample-plugins/defer/README
deleted file mode 100644
index d8990f8..0000000
--- a/sample/sample-plugins/defer/README
+++ /dev/null
@@ -1,16 +0,0 @@
-OpenVPN plugin examples.
-
-Examples provided:
-
-simple.c -- using the --auth-user-pass-verify callback,
- test deferred authentication.
-
-To build:
-
- ./build simple (Linux/BSD/etc.)
- ./winbuild simple (MinGW on Windows)
-
-To use in OpenVPN, add to config file:
-
- plugin simple.so (Linux/BSD/etc.)
- plugin simple.dll (MinGW on Windows)
diff --git a/sample/sample-plugins/defer/build b/sample/sample-plugins/defer/build
deleted file mode 100755
index ba41a39..0000000
--- a/sample/sample-plugins/defer/build
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-#
-# Build an OpenVPN plugin module on *nix. The argument should
-# be the base name of the C source file (without the .c).
-#
-
-# This directory is where we will look for openvpn-plugin.h
-CPPFLAGS="${CPPFLAGS:--I../../../include}"
-
-CC="${CC:-gcc}"
-CFLAGS="${CFLAGS:--O2 -Wall -g}"
-
-$CC $CPPFLAGS $CFLAGS -fPIC -c $1.c && \
-$CC $CFLAGS -fPIC -shared ${LDFLAGS} -Wl,-soname,$1.so -o $1.so $1.o -lc
diff --git a/sample/sample-plugins/defer/simple.c b/sample/sample-plugins/defer/simple.c
index d18695b..ba2e03e 100644
--- a/sample/sample-plugins/defer/simple.c
+++ b/sample/sample-plugins/defer/simple.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
+ * Copyright (C) 2002-2021 OpenVPN Inc <sales@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
@@ -54,13 +54,30 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include "openvpn-plugin.h"
-/* bool definitions */
-#define bool int
-#define true 1
-#define false 0
+/* Pointers to functions exported from openvpn */
+static plugin_log_t plugin_log = NULL;
+
+/*
+ * Constants indicating minimum API and struct versions by the functions
+ * in this plugin. Consult openvpn-plugin.h, look for:
+ * OPENVPN_PLUGIN_VERSION and OPENVPN_PLUGINv3_STRUCTVER
+ *
+ * Strictly speaking, this sample code only requires plugin_log, a feature
+ * of structver version 1. However, '1' lines up with ancient versions
+ * of openvpn that are past end-of-support. As such, we are requiring
+ * structver '5' here to indicate a desire for modern openvpn, rather
+ * than a need for any particular feature found in structver beyond '1'.
+ */
+#define OPENVPN_PLUGIN_VERSION_MIN 3
+#define OPENVPN_PLUGIN_STRUCTVER_MIN 5
/*
* Our context, where we keep our state.
@@ -76,6 +93,9 @@ struct plugin_per_client_context {
bool generated_pf_file;
};
+/* module name for plugin_log() */
+static char *MODULE = "defer/simple";
+
/*
* Given an environmental variable name, search
* the envp array for its value, returning it
@@ -130,28 +150,52 @@ atoi_null0(const char *str)
}
}
-OPENVPN_EXPORT openvpn_plugin_handle_t
-openvpn_plugin_open_v1(unsigned int *type_mask, const char *argv[], const char *envp[])
+/* Require a minimum OpenVPN Plugin API */
+OPENVPN_EXPORT int
+openvpn_plugin_min_version_required_v1()
{
+ return OPENVPN_PLUGIN_VERSION_MIN;
+}
+
+/* use v3 functions so we can use openvpn's logging and base64 etc. */
+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)
+{
+ const char **envp = args->envp; /* environment variables */
struct plugin_context *context;
- printf("FUNC: openvpn_plugin_open_v1\n");
+ if (v3structver < OPENVPN_PLUGIN_STRUCTVER_MIN)
+ {
+ fprintf(stderr, "%s: this plugin is incompatible with the running version of OpenVPN\n", MODULE);
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
+ /* Save global pointers to functions exported from openvpn */
+ plugin_log = args->callbacks->plugin_log;
+
+ plugin_log(PLOG_NOTE, MODULE, "FUNC: openvpn_plugin_open_v3");
/*
* Allocate our context
*/
context = (struct plugin_context *) calloc(1, sizeof(struct plugin_context));
+ if (!context)
+ {
+ goto error;
+ }
context->test_deferred_auth = atoi_null0(get_env("test_deferred_auth", envp));
- printf("TEST_DEFERRED_AUTH %d\n", context->test_deferred_auth);
+ plugin_log(PLOG_NOTE, MODULE, "TEST_DEFERRED_AUTH %d", context->test_deferred_auth);
context->test_packet_filter = atoi_null0(get_env("test_packet_filter", envp));
- printf("TEST_PACKET_FILTER %d\n", context->test_packet_filter);
+ plugin_log(PLOG_NOTE, MODULE, "TEST_PACKET_FILTER %d", context->test_packet_filter);
/*
* Which callbacks to intercept.
*/
- *type_mask =
+ ret->type_mask =
OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_UP)
|OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_DOWN)
|OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_ROUTE_UP)
@@ -161,157 +205,315 @@ openvpn_plugin_open_v1(unsigned int *type_mask, const char *argv[], const char *
|OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_CONNECT_V2)
|OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_DISCONNECT)
|OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_LEARN_ADDRESS)
- |OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_TLS_FINAL)
- |OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_ENABLE_PF);
+ |OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_TLS_FINAL);
- return (openvpn_plugin_handle_t) context;
+ /* ENABLE_PF should only be called if we're actually willing to do PF */
+ if (context->test_packet_filter)
+ {
+ ret->type_mask |= OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_ENABLE_PF);
+ }
+
+ ret->handle = (openvpn_plugin_handle_t *) context;
+ plugin_log(PLOG_NOTE, MODULE, "initialization succeeded");
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+
+error:
+ if (context)
+ {
+ free(context);
+ }
+ plugin_log(PLOG_NOTE, MODULE, "initialization failed");
+ return OPENVPN_PLUGIN_FUNC_ERROR;
}
static int
-auth_user_pass_verify(struct plugin_context *context, struct plugin_per_client_context *pcc, const char *argv[], const char *envp[])
+auth_user_pass_verify(struct plugin_context *context,
+ struct plugin_per_client_context *pcc,
+ const char *argv[], const char *envp[])
{
- if (context->test_deferred_auth)
+ if (!context->test_deferred_auth)
{
- /* get username/password from envp string array */
- const char *username = get_env("username", envp);
- const char *password = get_env("password", envp);
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+ }
+
+ /* get username/password from envp string array */
+ const char *username = get_env("username", envp);
+ const char *password = get_env("password", envp);
- /* get auth_control_file filename from envp string array*/
- const char *auth_control_file = get_env("auth_control_file", envp);
+ /* get auth_control_file filename from envp string array*/
+ const char *auth_control_file = get_env("auth_control_file", envp);
- printf("DEFER u='%s' p='%s' acf='%s'\n",
+ plugin_log(PLOG_NOTE, MODULE, "DEFER u='%s' p='%s' acf='%s'",
np(username),
np(password),
np(auth_control_file));
- /* Authenticate asynchronously in n seconds */
- if (auth_control_file)
- {
- char buf[256];
- int auth = 2;
- sscanf(username, "%d", &auth);
- snprintf(buf, sizeof(buf), "( sleep %d ; echo AUTH %s %d ; echo %d >%s ) &",
- context->test_deferred_auth,
- auth_control_file,
- auth,
- pcc->n_calls < auth,
- auth_control_file);
- printf("%s\n", buf);
- system(buf);
- pcc->n_calls++;
- return OPENVPN_PLUGIN_FUNC_DEFERRED;
- }
- else
- {
- return OPENVPN_PLUGIN_FUNC_ERROR;
- }
+ /* Authenticate asynchronously in n seconds */
+ if (!auth_control_file)
+ {
+ return OPENVPN_PLUGIN_FUNC_ERROR;
}
- else
+
+ /* we do not want to complicate our lives with having to wait()
+ * for child processes (so they are not zombiefied) *and* we MUST NOT
+ * fiddle with signal handlers (= shared with openvpn main), so
+ * we use double-fork() trick.
+ */
+
+ /* fork, sleep, succeed (no "real" auth done = always succeed) */
+ pid_t p1 = fork();
+ if (p1 < 0) /* Fork failed */
{
- return OPENVPN_PLUGIN_FUNC_SUCCESS;
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+ if (p1 > 0) /* parent process */
+ {
+ waitpid(p1, NULL, 0);
+ return OPENVPN_PLUGIN_FUNC_DEFERRED;
+ }
+
+ /* first gen child process, fork() again and exit() right away */
+ pid_t p2 = fork();
+ if (p2 < 0)
+ {
+ plugin_log(PLOG_ERR|PLOG_ERRNO, MODULE, "BACKGROUND: fork(2) failed");
+ exit(1);
+ }
+
+ if (p2 != 0) /* new parent: exit right away */
+ {
+ exit(0);
+ }
+
+ /* (grand-)child process
+ * - never call "return" now (would mess up openvpn)
+ * - return status is communicated by file
+ * - then exit()
+ */
+
+ /* do mighty complicated work that will really take time here... */
+ plugin_log(PLOG_NOTE, MODULE, "in async/deferred handler, sleep(%d)", context->test_deferred_auth);
+ sleep(context->test_deferred_auth);
+
+ /* now signal success state to openvpn */
+ int fd = open(auth_control_file, O_WRONLY);
+ if (fd < 0)
+ {
+ plugin_log(PLOG_ERR|PLOG_ERRNO, MODULE, "open('%s') failed", auth_control_file);
+ exit(1);
}
+
+ plugin_log(PLOG_NOTE, MODULE, "auth_user_pass_verify: done" );
+
+ if (write(fd, "1", 1) != 1)
+ {
+ plugin_log(PLOG_ERR|PLOG_ERRNO, MODULE, "write to '%s' failed", auth_control_file );
+ }
+ close(fd);
+
+ exit(0);
}
static int
tls_final(struct plugin_context *context, struct plugin_per_client_context *pcc, const char *argv[], const char *envp[])
{
- if (context->test_packet_filter)
+ if (!context->test_packet_filter) /* no PF testing, nothing to do */
{
- if (!pcc->generated_pf_file)
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+ }
+
+ if (pcc->generated_pf_file) /* we already have created a file */
+ {
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
+ const char *pff = get_env("pf_file", envp);
+ const char *cn = get_env("username", envp);
+ if (!pff || !cn) /* required vars missing */
+ {
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
+ pcc->generated_pf_file = true;
+
+ /* the PF API is, basically
+ * - OpenVPN sends a filename (pf_file) to the plugin
+ * - OpenVPN main loop will check every second if that file shows up
+ * - when it does, it will be read & used for the pf config
+ * the pre-created file needs to be removed in ...ENABLE_PF
+ * to make deferred PF setup work
+ *
+ * the regular PF hook does not know the client username or CN, so
+ * this is deferred to the TLS_FINAL hook which knows these things
+ */
+
+ /* do the double fork dance (see above for more verbose comments)
+ */
+ pid_t p1 = fork();
+ if (p1 < 0) /* Fork failed */
+ {
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+ if (p1 > 0) /* parent process */
+ {
+ waitpid(p1, NULL, 0);
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; /* no _DEFERRED here! */
+ }
+
+ /* first gen child process, fork() again and exit() right away */
+ pid_t p2 = fork();
+ if (p2 < 0)
+ {
+ plugin_log(PLOG_ERR|PLOG_ERRNO, MODULE, "BACKGROUND: fork(2) failed");
+ exit(1);
+ }
+
+ if (p2 != 0) /* new parent: exit right away */
+ {
+ exit(0);
+ }
+
+ /* (grand-)child process
+ * - never call "return" now (would mess up openvpn)
+ * - return status is communicated by file
+ * - then exit()
+ */
+
+ /* at this point, the plugin can take its time, because OpenVPN will
+ * no longer block waiting for the call to finish
+ *
+ * in this example, we build a PF file by copying over a file
+ * named "<username>.pf" to the OpenVPN-provided pf file name
+ *
+ * a real example could do a LDAP lookup, a REST call, ...
+ */
+ plugin_log(PLOG_NOTE, MODULE, "in async/deferred tls_final handler, sleep(%d)", context->test_packet_filter);
+ sleep(context->test_packet_filter);
+
+ char buf[256];
+ snprintf(buf, sizeof(buf), "%s.pf", cn );
+
+ /* there is a small race condition here - OpenVPN could detect our
+ * file while we have only written half of it. So "perfect" code
+ * needs to create this with a temp file name, and then rename() it
+ * after it has been written. But I am lazy.
+ */
+
+ int w_fd = open( pff, O_WRONLY|O_CREAT, 0600 );
+ if (w_fd < 0)
+ {
+ plugin_log(PLOG_ERR|PLOG_ERRNO, MODULE, "can't write to '%s'", pff);
+ exit(0);
+ }
+
+ int r_fd = open( buf, O_RDONLY );
+ if (r_fd < 0)
+ {
+ plugin_log(PLOG_ERR|PLOG_ERRNO, MODULE, "can't read '%s', creating empty pf file", buf);
+ close(w_fd);
+ exit(0);
+ }
+
+ char data[1024];
+
+ int r;
+ do
+ {
+ r = read(r_fd, data, sizeof(data));
+ if (r < 0)
{
- const char *pff = get_env("pf_file", envp);
- const char *cn = get_env("username", envp);
- if (pff && cn)
- {
- char buf[256];
- snprintf(buf, sizeof(buf), "( sleep %d ; echo PF %s/%s ; cp \"%s.pf\" \"%s\" ) &",
- context->test_packet_filter, cn, pff, cn, pff);
- printf("%s\n", buf);
- system(buf);
- pcc->generated_pf_file = true;
- return OPENVPN_PLUGIN_FUNC_SUCCESS;
- }
- else
- {
- return OPENVPN_PLUGIN_FUNC_ERROR;
- }
+ plugin_log(PLOG_ERR|PLOG_ERRNO, MODULE, "error reading '%s'", buf);
+ close(r_fd);
+ close(w_fd);
+ exit(0);
}
- else
+ int w = write(w_fd, data, r);
+ if (w < 0 || w != r)
{
- return OPENVPN_PLUGIN_FUNC_ERROR;
+ plugin_log(PLOG_ERR|PLOG_ERRNO, MODULE, "error writing %d bytes to '%s'", r, pff);
+ close(r_fd);
+ close(w_fd);
+ exit(0);
}
}
- else
- {
- return OPENVPN_PLUGIN_FUNC_SUCCESS;
- }
+ while(r > 0);
+
+ plugin_log(PLOG_NOTE, MODULE, "copied PF config from '%s' to '%s', job done", buf, pff);
+ exit(0);
}
OPENVPN_EXPORT int
-openvpn_plugin_func_v2(openvpn_plugin_handle_t handle,
- const int type,
- const char *argv[],
- const char *envp[],
- void *per_client_context,
- struct openvpn_plugin_string_list **return_list)
+openvpn_plugin_func_v3(const int v3structver,
+ struct openvpn_plugin_args_func_in const *args,
+ struct openvpn_plugin_args_func_return *ret)
{
- struct plugin_context *context = (struct plugin_context *) handle;
- struct plugin_per_client_context *pcc = (struct plugin_per_client_context *) per_client_context;
- switch (type)
+ if (v3structver < OPENVPN_PLUGIN_STRUCTVER_MIN)
+ {
+ fprintf(stderr, "%s: this plugin is incompatible with the running version of OpenVPN\n", MODULE);
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+ const char **argv = args->argv;
+ const char **envp = args->envp;
+ struct plugin_context *context = (struct plugin_context *) args->handle;
+ struct plugin_per_client_context *pcc = (struct plugin_per_client_context *) args->per_client_context;
+ switch (args->type)
{
case OPENVPN_PLUGIN_UP:
- printf("OPENVPN_PLUGIN_UP\n");
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_UP");
return OPENVPN_PLUGIN_FUNC_SUCCESS;
case OPENVPN_PLUGIN_DOWN:
- printf("OPENVPN_PLUGIN_DOWN\n");
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_DOWN");
return OPENVPN_PLUGIN_FUNC_SUCCESS;
case OPENVPN_PLUGIN_ROUTE_UP:
- printf("OPENVPN_PLUGIN_ROUTE_UP\n");
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_ROUTE_UP");
return OPENVPN_PLUGIN_FUNC_SUCCESS;
case OPENVPN_PLUGIN_IPCHANGE:
- printf("OPENVPN_PLUGIN_IPCHANGE\n");
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_IPCHANGE");
return OPENVPN_PLUGIN_FUNC_SUCCESS;
case OPENVPN_PLUGIN_TLS_VERIFY:
- printf("OPENVPN_PLUGIN_TLS_VERIFY\n");
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_TLS_VERIFY");
return OPENVPN_PLUGIN_FUNC_SUCCESS;
case OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY:
- printf("OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY\n");
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY");
return auth_user_pass_verify(context, pcc, argv, envp);
case OPENVPN_PLUGIN_CLIENT_CONNECT_V2:
- printf("OPENVPN_PLUGIN_CLIENT_CONNECT_V2\n");
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_CLIENT_CONNECT_V2");
return OPENVPN_PLUGIN_FUNC_SUCCESS;
case OPENVPN_PLUGIN_CLIENT_DISCONNECT:
- printf("OPENVPN_PLUGIN_CLIENT_DISCONNECT\n");
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_CLIENT_DISCONNECT");
return OPENVPN_PLUGIN_FUNC_SUCCESS;
case OPENVPN_PLUGIN_LEARN_ADDRESS:
- printf("OPENVPN_PLUGIN_LEARN_ADDRESS\n");
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_LEARN_ADDRESS");
return OPENVPN_PLUGIN_FUNC_SUCCESS;
case OPENVPN_PLUGIN_TLS_FINAL:
- printf("OPENVPN_PLUGIN_TLS_FINAL\n");
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_TLS_FINAL");
return tls_final(context, pcc, argv, envp);
case OPENVPN_PLUGIN_ENABLE_PF:
- printf("OPENVPN_PLUGIN_ENABLE_PF\n");
- if (context->test_packet_filter)
- {
- return OPENVPN_PLUGIN_FUNC_SUCCESS;
- }
- else
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_ENABLE_PF");
+
+ /* OpenVPN pre-creates the file, which gets in the way of
+ * deferred pf setup - so remove it here, and re-create
+ * it in the background handler (in tls_final()) when ready
+ */
+ const char *pff = get_env("pf_file", envp);
+ if (pff)
{
- return OPENVPN_PLUGIN_FUNC_ERROR;
+ (void) unlink(pff);
}
+ return OPENVPN_PLUGIN_FUNC_SUCCESS; /* must succeed */
default:
- printf("OPENVPN_PLUGIN_?\n");
+ plugin_log(PLOG_NOTE, MODULE, "OPENVPN_PLUGIN_?");
return OPENVPN_PLUGIN_FUNC_ERROR;
}
}
@@ -319,14 +521,14 @@ openvpn_plugin_func_v2(openvpn_plugin_handle_t handle,
OPENVPN_EXPORT void *
openvpn_plugin_client_constructor_v1(openvpn_plugin_handle_t handle)
{
- printf("FUNC: openvpn_plugin_client_constructor_v1\n");
+ plugin_log(PLOG_NOTE, MODULE, "FUNC: openvpn_plugin_client_constructor_v1");
return calloc(1, sizeof(struct plugin_per_client_context));
}
OPENVPN_EXPORT void
openvpn_plugin_client_destructor_v1(openvpn_plugin_handle_t handle, void *per_client_context)
{
- printf("FUNC: openvpn_plugin_client_destructor_v1\n");
+ plugin_log(PLOG_NOTE, MODULE, "FUNC: openvpn_plugin_client_destructor_v1");
free(per_client_context);
}
@@ -334,6 +536,6 @@ OPENVPN_EXPORT void
openvpn_plugin_close_v1(openvpn_plugin_handle_t handle)
{
struct plugin_context *context = (struct plugin_context *) handle;
- printf("FUNC: openvpn_plugin_close_v1\n");
+ plugin_log(PLOG_NOTE, MODULE, "FUNC: openvpn_plugin_close_v1");
free(context);
}
diff --git a/sample/sample-plugins/keying-material-exporter-demo/build b/sample/sample-plugins/keying-material-exporter-demo/build
deleted file mode 100755
index bbb05f7..0000000
--- a/sample/sample-plugins/keying-material-exporter-demo/build
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-#
-# Build an OpenVPN plugin module on *nix. The argument should
-# be the base name of the C source file (without the .c).
-#
-
-# This directory is where we will look for openvpn-plugin.h
-CPPFLAGS="${CPPFLAGS:--I../../..}"
-
-CC="${CC:-gcc}"
-CFLAGS="${CFLAGS:--O2 -Wall -g}"
-
-$CC $CPPFLAGS $CFLAGS -fPIC -c $1.c && \
-$CC $CFLAGS -fPIC -shared $LDFLAGS -Wl,-soname,$1.so -o $1.so $1.o -lc
diff --git a/sample/sample-plugins/keying-material-exporter-demo/keyingmaterialexporter.c b/sample/sample-plugins/keying-material-exporter-demo/keyingmaterialexporter.c
index 5d3ca14..787fc54 100644
--- a/sample/sample-plugins/keying-material-exporter-demo/keyingmaterialexporter.c
+++ b/sample/sample-plugins/keying-material-exporter-demo/keyingmaterialexporter.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
+ * Copyright (C) 2002-2021 OpenVPN Inc <sales@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
@@ -27,8 +27,6 @@
* See the README file for build instructions.
*/
-#define ENABLE_CRYPTO
-
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -94,6 +92,12 @@ openvpn_plugin_open_v3(const int version,
{
struct plugin *plugin = calloc(1, sizeof(*plugin));
+ if (plugin == NULL)
+ {
+ printf("PLUGIN: allocating memory for context failed\n");
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
plugin->type = get_env("remote_1", args->envp) ? CLIENT : SERVER;
plugin->log = args->callbacks->plugin_log;
@@ -232,7 +236,8 @@ tls_final(struct openvpn_plugin_args_func_in const *args,
snprintf(sess->key, sizeof(sess->key) - 1, "%s", key);
ovpn_note("app session key: %s", sess->key);
- switch (plugin->type) {
+ switch (plugin->type)
+ {
case SERVER:
server_store(args);
break;
@@ -251,7 +256,8 @@ openvpn_plugin_func_v3(const int version,
struct openvpn_plugin_args_func_in const *args,
struct openvpn_plugin_args_func_return *rv)
{
- switch (args->type) {
+ switch (args->type)
+ {
case OPENVPN_PLUGIN_TLS_VERIFY:
return tls_verify(args);
diff --git a/sample/sample-plugins/log/build b/sample/sample-plugins/log/build
deleted file mode 100755
index c07ec40..0000000
--- a/sample/sample-plugins/log/build
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-#
-# Build an OpenVPN plugin module on *nix. The argument should
-# be the base name of the C source file (without the .c).
-#
-
-# This directory is where we will look for openvpn-plugin.h
-CPPFLAGS="${CPPFLAGS:--I../../../include}"
-
-CC="${CC:-gcc}"
-CFLAGS="${CFLAGS:--O2 -Wall -g}"
-
-$CC $CPPFLAGS $CFLAGS -fPIC -c $1.c && \
-$CC $CFLAGS -fPIC -shared $LDFLAGS -Wl,-soname,$1.so -o $1.so $1.o -lc
diff --git a/sample/sample-plugins/log/log.c b/sample/sample-plugins/log/log.c
index ecf62c0..661ec5d 100644
--- a/sample/sample-plugins/log/log.c
+++ b/sample/sample-plugins/log/log.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
+ * Copyright (C) 2002-2021 OpenVPN Inc <sales@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
@@ -78,6 +78,11 @@ openvpn_plugin_open_v1(unsigned int *type_mask, const char *argv[], const char *
* Allocate our context
*/
context = (struct plugin_context *) calloc(1, sizeof(struct plugin_context));
+ if (context == NULL)
+ {
+ printf("PLUGIN: allocating memory for context failed\n");
+ return NULL;
+ }
/*
* Set the username/password we will require.
@@ -156,11 +161,15 @@ show(const int type, const char *argv[], const char *envp[])
printf("ARGV\n");
for (i = 0; argv[i] != NULL; ++i)
+ {
printf("%d '%s'\n", (int)i, argv[i]);
+ }
printf("ENVP\n");
for (i = 0; envp[i] != NULL; ++i)
+ {
printf("%d '%s'\n", (int)i, envp[i]);
+ }
}
OPENVPN_EXPORT int
diff --git a/sample/sample-plugins/log/log_v3.c b/sample/sample-plugins/log/log_v3.c
index c972951..7ae77a8 100644
--- a/sample/sample-plugins/log/log_v3.c
+++ b/sample/sample-plugins/log/log_v3.c
@@ -5,8 +5,8 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
- * Copyright (C) 2010 David Sommerseth <dazo@users.sourceforge.net>
+ * Copyright (C) 2002-2021 OpenVPN Inc <sales@openvpn.net>
+ * Copyright (C) 2010-2021 David Sommerseth <dazo@eurephia.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -35,8 +35,6 @@
#include <string.h>
#include <stdlib.h>
-#define ENABLE_CRYPTO
-
#include "openvpn-plugin.h"
/*
@@ -115,6 +113,11 @@ openvpn_plugin_open_v3(const int v3structver,
/* Allocate our context */
context = (struct plugin_context *) calloc(1, sizeof(struct plugin_context));
+ if (context == NULL)
+ {
+ printf("PLUGIN: allocating memory for context failed\n");
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
/* Set the username/password we will require. */
context->username = "foo";
@@ -179,11 +182,15 @@ show(const int type, const char *argv[], const char *envp[])
printf("ARGV\n");
for (i = 0; argv[i] != NULL; ++i)
+ {
printf("%d '%s'\n", (int)i, argv[i]);
+ }
printf("ENVP\n");
for (i = 0; envp[i] != NULL; ++i)
+ {
printf("%d '%s'\n", (int)i, envp[i]);
+ }
}
static void
@@ -196,7 +203,7 @@ x509_print_info(X509 *x509crt)
X509_NAME *x509_name;
X509_NAME_ENTRY *ent;
const char *objbuf;
- unsigned char *buf;
+ unsigned char *buf = NULL;
x509_name = X509_get_subject_name(x509crt);
n = X509_NAME_entry_count(x509_name);
diff --git a/sample/sample-plugins/simple/README b/sample/sample-plugins/simple/README
deleted file mode 100644
index 4400cd3..0000000
--- a/sample/sample-plugins/simple/README
+++ /dev/null
@@ -1,16 +0,0 @@
-OpenVPN plugin examples.
-
-Examples provided:
-
-simple.c -- using the --auth-user-pass-verify callback, verify
- that the username/password is "foo"/"bar".
-
-To build:
-
- ./build simple (Linux/BSD/etc.)
- ./winbuild simple (MinGW on Windows)
-
-To use in OpenVPN, add to config file:
-
- plugin simple.so (Linux/BSD/etc.)
- plugin simple.dll (MinGW on Windows)
diff --git a/sample/sample-plugins/simple/base64.c b/sample/sample-plugins/simple/base64.c
index bd95e79..363a123 100644
--- a/sample/sample-plugins/simple/base64.c
+++ b/sample/sample-plugins/simple/base64.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2017 David Sommerseth <davids@openvpn.net>
+ * Copyright (C) 2017-2021 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
diff --git a/sample/sample-plugins/simple/build b/sample/sample-plugins/simple/build
deleted file mode 100755
index bbb05f7..0000000
--- a/sample/sample-plugins/simple/build
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-#
-# Build an OpenVPN plugin module on *nix. The argument should
-# be the base name of the C source file (without the .c).
-#
-
-# This directory is where we will look for openvpn-plugin.h
-CPPFLAGS="${CPPFLAGS:--I../../..}"
-
-CC="${CC:-gcc}"
-CFLAGS="${CFLAGS:--O2 -Wall -g}"
-
-$CC $CPPFLAGS $CFLAGS -fPIC -c $1.c && \
-$CC $CFLAGS -fPIC -shared $LDFLAGS -Wl,-soname,$1.so -o $1.so $1.o -lc
diff --git a/sample/sample-plugins/simple/simple.c b/sample/sample-plugins/simple/simple.c
index 950c547..0f26dd2 100644
--- a/sample/sample-plugins/simple/simple.c
+++ b/sample/sample-plugins/simple/simple.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
+ * Copyright (C) 2002-2021 OpenVPN Inc <sales@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
@@ -80,6 +80,11 @@ openvpn_plugin_open_v1(unsigned int *type_mask, const char *argv[], const char *
* Allocate our context
*/
context = (struct plugin_context *) calloc(1, sizeof(struct plugin_context));
+ if (context == NULL)
+ {
+ printf("PLUGIN: allocating memory for context failed\n");
+ return NULL;
+ }
/*
* Set the username/password we will require.
diff --git a/sample/sample-windows/sample.ovpn b/sample/sample-windows/sample.ovpn
index 5accd57..51e3274 100755
--- a/sample/sample-windows/sample.ovpn
+++ b/sample/sample-windows/sample.ovpn
@@ -68,7 +68,7 @@ ifconfig 10.3.0.1 255.255.255.0
#
# You can also generate key.txt manually
# with the following command:
-# openvpn --genkey --secret key.txt
+# openvpn --genkey secret key.txt
#
# key must match on both ends of the connection,
# so you should generate it on one machine and