Package: openvpn
Version: 2.4.5-1
Severity: important
Tags: patch
Dear Maintainer,
users of yubikey or other PKCS11 based authetication are not able to use this
feature with the current package.
Upstream reference: https://community.openvpn.net/openvpn/ticket/538
I was able to fix this problem by building the current debian package with the
patch provided upstream:
https://community.openvpn.net/openvpn/attachment/ticket/538/openvpn-2.4.5_bug-538.patch
Please consider including this patch in your package.
Regards,
Robert Haist
-- System Information:
Debian Release: buster/sid
APT prefers testing
APT policy: (650, 'testing')
Architecture: amd64 (x86_64)
Kernel: Linux 4.16.0-1-amd64 (SMP w/8 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8),
LANGUAGE=en_US:en (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
Versions of packages openvpn depends on:
ii debconf [debconf-2.0] 1.5.66
ii iproute2 4.16.0-4
ii libc6 2.27-3
ii liblz4-1 1.8.2-1
ii liblzo2-2 2.10-0.1
ii libpam0g 1.1.8-3.7
ii libpkcs11-helper1 1.22-4
ii libssl1.1 1.1.0h-4
ii libsystemd0 238-5
ii lsb-base 9.20170808
Versions of packages openvpn recommends:
ii easy-rsa 3.0.4-1
Versions of packages openvpn suggests:
ii openssl 1.1.0h-4
pn resolvconf <none>
-- debconf information excluded
diff -Naur openvpn-2.4.5/src/openvpn/console.h
openvpn-2.4.5_bug-538/src/openvpn/console.h
--- openvpn-2.4.5/src/openvpn/console.h 2018-03-01 08:22:17.000000000 +0100
+++ openvpn-2.4.5_bug-538/src/openvpn/console.h 2018-03-09 15:01:36.825094859
+0100
@@ -116,4 +116,22 @@
return query_user_exec();
}
+/**
+ * A plain "make Gert happy" wrapper over built-in user querying method.
+ * Same arguments as @query_user_add
+ *
+ * Allows to use built-in method for PKCS11 PIN prompt regardless of
+ * the systemd support status and presence,
+ * see https://community.openvpn.net/openvpn/ticket/538 for details.
+*/
+static inline bool
+query_user_builtin_SINGLE(char *prompt, size_t prompt_len,
+ char *resp, size_t resp_len,
+ bool echo)
+{
+ query_user_clear();
+ query_user_add(prompt, prompt_len, resp, resp_len, echo);
+ return query_user_exec_builtin();
+}
+
#endif /* ifndef CONSOLE_H */
diff -Naur openvpn-2.4.5/src/openvpn/misc.c
openvpn-2.4.5_bug-538/src/openvpn/misc.c
--- openvpn-2.4.5/src/openvpn/misc.c 2018-03-01 08:22:19.000000000 +0100
+++ openvpn-2.4.5_bug-538/src/openvpn/misc.c 2018-03-09 15:02:11.056279505
+0100
@@ -930,10 +930,19 @@
struct buffer user_prompt = alloc_buf_gc(128, &gc);
buf_printf(&user_prompt, "NEED-OK|%s|%s:", prefix, up->username);
- if (!query_user_SINGLE(BSTR(&user_prompt), BLEN(&user_prompt),
- up->password, USER_PASS_LEN, false))
- {
- msg(M_FATAL, "ERROR: could not read %s ok-confirmation from
stdin", prefix);
+ if (flags & GET_USER_PASS_FORCE_BUILTIN) {
+ if (!query_user_builtin_SINGLE(BSTR(&user_prompt),
BLEN(&user_prompt),
+ up->password, USER_PASS_LEN, false))
+ {
+ msg(M_FATAL, "ERROR: could not read %s ok-confirmation
from stdin", prefix);
+ }
+ }
+ else {
+ if (!query_user_SINGLE(BSTR(&user_prompt), BLEN(&user_prompt),
+ up->password, USER_PASS_LEN, false))
+ {
+ msg(M_FATAL, "ERROR: could not read %s ok-confirmation
from stdin", prefix);
+ }
}
if (!strlen(up->password))
@@ -941,7 +950,7 @@
strcpy(up->password, "ok");
}
}
- else if (flags & GET_USER_PASS_INLINE_CREDS)
+ else if (flags & GET_USER_PASS_NEED_OK)
{
struct buffer buf;
buf_set_read(&buf, (uint8_t *) auth_file, strlen(auth_file) + 1);
@@ -1030,10 +1039,19 @@
buf_printf(&challenge, "CHALLENGE: %s",
ac->challenge_text);
buf_set_write(&packed_resp, (uint8_t *)up->password,
USER_PASS_LEN);
- if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge),
- response, USER_PASS_LEN,
BOOL_CAST(ac->flags&CR_ECHO)))
- {
- msg(M_FATAL, "ERROR: could not read challenge response
from stdin");
+ if (flags & GET_USER_PASS_FORCE_BUILTIN) {
+ if (!query_user_builtin_SINGLE(BSTR(&challenge),
BLEN(&challenge),
+ response, USER_PASS_LEN,
BOOL_CAST(ac->flags&CR_ECHO)))
+ {
+ msg(M_FATAL, "ERROR: could not read challenge
response from stdin");
+ }
+ }
+ else {
+ if (!query_user_SINGLE(BSTR(&challenge),
BLEN(&challenge),
+ response, USER_PASS_LEN,
BOOL_CAST(ac->flags&CR_ECHO)))
+ {
+ msg(M_FATAL, "ERROR: could not read challenge
response from stdin");
+ }
}
strncpynt(up->username, ac->user, USER_PASS_LEN);
buf_printf(&packed_resp, "CRV1::%s::%s", ac->state_id,
response);
@@ -1065,9 +1083,17 @@
up->password, USER_PASS_LEN, false);
}
- if (!query_user_exec() )
- {
- msg(M_FATAL, "ERROR: Failed retrieving username or
password");
+ if (flags & GET_USER_PASS_FORCE_BUILTIN) {
+ if (!query_user_exec_builtin() )
+ {
+ msg(M_FATAL, "ERROR: Failed retrieving username or
password");
+ }
+ }
+ else {
+ if (!query_user_exec() )
+ {
+ msg(M_FATAL, "ERROR: Failed retrieving username or
password");
+ }
}
if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
@@ -1088,11 +1114,21 @@
challenge = alloc_buf_gc(14+strlen(auth_challenge), &gc);
buf_printf(&challenge, "CHALLENGE: %s", auth_challenge);
- if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge),
- response, USER_PASS_LEN,
- BOOL_CAST(flags &
GET_USER_PASS_STATIC_CHALLENGE_ECHO)))
- {
- msg(M_FATAL, "ERROR: could not retrieve static
challenge response");
+ if (flags & GET_USER_PASS_FORCE_BUILTIN) {
+ if (!query_user_builtin_SINGLE(BSTR(&challenge),
BLEN(&challenge),
+ response, USER_PASS_LEN,
+ BOOL_CAST(flags &
GET_USER_PASS_STATIC_CHALLENGE_ECHO)))
+ {
+ msg(M_FATAL, "ERROR: could not retrieve static
challenge response");
+ }
+ }
+ else {
+ if (!query_user_SINGLE(BSTR(&challenge),
BLEN(&challenge),
+ response, USER_PASS_LEN,
+ BOOL_CAST(flags &
GET_USER_PASS_STATIC_CHALLENGE_ECHO)))
+ {
+ msg(M_FATAL, "ERROR: could not retrieve static
challenge response");
+ }
}
if (openvpn_base64_encode(up->password,
strlen(up->password), &pw64) == -1
|| openvpn_base64_encode(response, strlen(response),
&resp64) == -1)
diff -Naur openvpn-2.4.5/src/openvpn/misc.h
openvpn-2.4.5_bug-538/src/openvpn/misc.h
--- openvpn-2.4.5/src/openvpn/misc.h 2018-03-01 08:22:19.000000000 +0100
+++ openvpn-2.4.5_bug-538/src/openvpn/misc.h 2018-03-09 15:02:07.946262729
+0100
@@ -232,7 +232,9 @@
#define GET_USER_PASS_STATIC_CHALLENGE (1<<8) /* SCRV1 protocol --
static challenge */
#define GET_USER_PASS_STATIC_CHALLENGE_ECHO (1<<9) /* SCRV1 protocol -- echo
response */
-#define GET_USER_PASS_INLINE_CREDS (1<<10) /* indicates that auth_file is
actually inline creds */
+#define GET_USER_PASS_INLINE_CREDS (1<<10)
+
+#define GET_USER_PASS_FORCE_BUILTIN (1<<11) /* force builtin prompt to work
around 538 */
bool get_user_pass_cr(struct user_pass *up,
const char *auth_file,
diff -Naur openvpn-2.4.5/src/openvpn/pkcs11.c
openvpn-2.4.5_bug-538/src/openvpn/pkcs11.c
--- openvpn-2.4.5/src/openvpn/pkcs11.c 2018-03-01 08:22:17.000000000 +0100
+++ openvpn-2.4.5_bug-538/src/openvpn/pkcs11.c 2018-03-09 15:02:01.982230559
+0100
@@ -257,7 +257,7 @@
&token_pass,
NULL,
prompt,
-
GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY|GET_USER_PASS_NOFATAL
+
GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY|GET_USER_PASS_NOFATAL|GET_USER_PASS_FORCE_BUILTIN
)
)
{
@@ -813,7 +813,7 @@
ASSERT(token!=NULL);
buf_printf(&pass_prompt, "Please enter '%s' token PIN or 'cancel': ",
token->display);
- if (!query_user_SINGLE(BSTR(&pass_prompt), BLEN(&pass_prompt),
+ if (!query_user_builtin_SINGLE(BSTR(&pass_prompt), BLEN(&pass_prompt),
pin, pin_max, false))
{
msg(M_FATAL, "Could not retrieve the PIN");
diff -Naur openvpn-2.4.5/src/openvpn/console.h
openvpn-2.4.5_bug-538/src/openvpn/console.h
--- openvpn-2.4.5/src/openvpn/console.h 2018-03-01 08:22:17.000000000 +0100
+++ openvpn-2.4.5_bug-538/src/openvpn/console.h 2018-03-09 15:01:36.825094859
+0100
@@ -116,4 +116,22 @@
return query_user_exec();
}
+/**
+ * A plain "make Gert happy" wrapper over built-in user querying method.
+ * Same arguments as @query_user_add
+ *
+ * Allows to use built-in method for PKCS11 PIN prompt regardless of
+ * the systemd support status and presence,
+ * see https://community.openvpn.net/openvpn/ticket/538 for details.
+*/
+static inline bool
+query_user_builtin_SINGLE(char *prompt, size_t prompt_len,
+ char *resp, size_t resp_len,
+ bool echo)
+{
+ query_user_clear();
+ query_user_add(prompt, prompt_len, resp, resp_len, echo);
+ return query_user_exec_builtin();
+}
+
#endif /* ifndef CONSOLE_H */
diff -Naur openvpn-2.4.5/src/openvpn/misc.c
openvpn-2.4.5_bug-538/src/openvpn/misc.c
--- openvpn-2.4.5/src/openvpn/misc.c 2018-03-01 08:22:19.000000000 +0100
+++ openvpn-2.4.5_bug-538/src/openvpn/misc.c 2018-03-09 15:02:11.056279505
+0100
@@ -930,10 +930,19 @@
struct buffer user_prompt = alloc_buf_gc(128, &gc);
buf_printf(&user_prompt, "NEED-OK|%s|%s:", prefix, up->username);
- if (!query_user_SINGLE(BSTR(&user_prompt), BLEN(&user_prompt),
- up->password, USER_PASS_LEN, false))
- {
- msg(M_FATAL, "ERROR: could not read %s ok-confirmation from
stdin", prefix);
+ if (flags & GET_USER_PASS_FORCE_BUILTIN) {
+ if (!query_user_builtin_SINGLE(BSTR(&user_prompt),
BLEN(&user_prompt),
+ up->password, USER_PASS_LEN, false))
+ {
+ msg(M_FATAL, "ERROR: could not read %s ok-confirmation
from stdin", prefix);
+ }
+ }
+ else {
+ if (!query_user_SINGLE(BSTR(&user_prompt), BLEN(&user_prompt),
+ up->password, USER_PASS_LEN, false))
+ {
+ msg(M_FATAL, "ERROR: could not read %s ok-confirmation
from stdin", prefix);
+ }
}
if (!strlen(up->password))
@@ -941,7 +950,7 @@
strcpy(up->password, "ok");
}
}
- else if (flags & GET_USER_PASS_INLINE_CREDS)
+ else if (flags & GET_USER_PASS_NEED_OK)
{
struct buffer buf;
buf_set_read(&buf, (uint8_t *) auth_file, strlen(auth_file) + 1);
@@ -1030,10 +1039,19 @@
buf_printf(&challenge, "CHALLENGE: %s",
ac->challenge_text);
buf_set_write(&packed_resp, (uint8_t *)up->password,
USER_PASS_LEN);
- if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge),
- response, USER_PASS_LEN,
BOOL_CAST(ac->flags&CR_ECHO)))
- {
- msg(M_FATAL, "ERROR: could not read challenge response
from stdin");
+ if (flags & GET_USER_PASS_FORCE_BUILTIN) {
+ if (!query_user_builtin_SINGLE(BSTR(&challenge),
BLEN(&challenge),
+ response, USER_PASS_LEN,
BOOL_CAST(ac->flags&CR_ECHO)))
+ {
+ msg(M_FATAL, "ERROR: could not read challenge
response from stdin");
+ }
+ }
+ else {
+ if (!query_user_SINGLE(BSTR(&challenge),
BLEN(&challenge),
+ response, USER_PASS_LEN,
BOOL_CAST(ac->flags&CR_ECHO)))
+ {
+ msg(M_FATAL, "ERROR: could not read challenge
response from stdin");
+ }
}
strncpynt(up->username, ac->user, USER_PASS_LEN);
buf_printf(&packed_resp, "CRV1::%s::%s", ac->state_id,
response);
@@ -1065,9 +1083,17 @@
up->password, USER_PASS_LEN, false);
}
- if (!query_user_exec() )
- {
- msg(M_FATAL, "ERROR: Failed retrieving username or
password");
+ if (flags & GET_USER_PASS_FORCE_BUILTIN) {
+ if (!query_user_exec_builtin() )
+ {
+ msg(M_FATAL, "ERROR: Failed retrieving username or
password");
+ }
+ }
+ else {
+ if (!query_user_exec() )
+ {
+ msg(M_FATAL, "ERROR: Failed retrieving username or
password");
+ }
}
if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
@@ -1088,11 +1114,21 @@
challenge = alloc_buf_gc(14+strlen(auth_challenge), &gc);
buf_printf(&challenge, "CHALLENGE: %s", auth_challenge);
- if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge),
- response, USER_PASS_LEN,
- BOOL_CAST(flags &
GET_USER_PASS_STATIC_CHALLENGE_ECHO)))
- {
- msg(M_FATAL, "ERROR: could not retrieve static
challenge response");
+ if (flags & GET_USER_PASS_FORCE_BUILTIN) {
+ if (!query_user_builtin_SINGLE(BSTR(&challenge),
BLEN(&challenge),
+ response, USER_PASS_LEN,
+ BOOL_CAST(flags &
GET_USER_PASS_STATIC_CHALLENGE_ECHO)))
+ {
+ msg(M_FATAL, "ERROR: could not retrieve static
challenge response");
+ }
+ }
+ else {
+ if (!query_user_SINGLE(BSTR(&challenge),
BLEN(&challenge),
+ response, USER_PASS_LEN,
+ BOOL_CAST(flags &
GET_USER_PASS_STATIC_CHALLENGE_ECHO)))
+ {
+ msg(M_FATAL, "ERROR: could not retrieve static
challenge response");
+ }
}
if (openvpn_base64_encode(up->password,
strlen(up->password), &pw64) == -1
|| openvpn_base64_encode(response, strlen(response),
&resp64) == -1)
diff -Naur openvpn-2.4.5/src/openvpn/misc.h
openvpn-2.4.5_bug-538/src/openvpn/misc.h
--- openvpn-2.4.5/src/openvpn/misc.h 2018-03-01 08:22:19.000000000 +0100
+++ openvpn-2.4.5_bug-538/src/openvpn/misc.h 2018-03-09 15:02:07.946262729
+0100
@@ -232,7 +232,9 @@
#define GET_USER_PASS_STATIC_CHALLENGE (1<<8) /* SCRV1 protocol --
static challenge */
#define GET_USER_PASS_STATIC_CHALLENGE_ECHO (1<<9) /* SCRV1 protocol -- echo
response */
-#define GET_USER_PASS_INLINE_CREDS (1<<10) /* indicates that auth_file is
actually inline creds */
+#define GET_USER_PASS_INLINE_CREDS (1<<10)
+
+#define GET_USER_PASS_FORCE_BUILTIN (1<<11) /* force builtin prompt to work
around 538 */
bool get_user_pass_cr(struct user_pass *up,
const char *auth_file,
diff -Naur openvpn-2.4.5/src/openvpn/pkcs11.c
openvpn-2.4.5_bug-538/src/openvpn/pkcs11.c
--- openvpn-2.4.5/src/openvpn/pkcs11.c 2018-03-01 08:22:17.000000000 +0100
+++ openvpn-2.4.5_bug-538/src/openvpn/pkcs11.c 2018-03-09 15:02:01.982230559
+0100
@@ -257,7 +257,7 @@
&token_pass,
NULL,
prompt,
-
GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY|GET_USER_PASS_NOFATAL
+
GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY|GET_USER_PASS_NOFATAL|GET_USER_PASS_FORCE_BUILTIN
)
)
{
@@ -813,7 +813,7 @@
ASSERT(token!=NULL);
buf_printf(&pass_prompt, "Please enter '%s' token PIN or 'cancel': ",
token->display);
- if (!query_user_SINGLE(BSTR(&pass_prompt), BLEN(&pass_prompt),
+ if (!query_user_builtin_SINGLE(BSTR(&pass_prompt), BLEN(&pass_prompt),
pin, pin_max, false))
{
msg(M_FATAL, "Could not retrieve the PIN");