From 7e2129f8a906f3858dc3792e1519332bf26ced99 Mon Sep 17 00:00:00 2001 From: Daniel Lenski Date: Thu, 13 Jun 2019 10:53:27 -0500 Subject: [PATCH] ensure that openconnect_disable_{dtls,ipv6} do nothing if vpninfo has ever been connected Both openconnect_disable_dtls() and openconnect_disable_ipv6() now return int (0 or -EINVAL), and are used in CLI argument processing. Ideally, we would allow these to be used when IPv6 or DTLS/ESP are not currently in use, but we do not have sufficiently reliable cross-protocol indicators of these. The main use case for both of these functions is disable a problematic feature prior to initial connection. Signed-off-by: Daniel Lenski --- gpst.c | 3 +- .../libopenconnect/LibOpenConnect.java | 4 +-- jni.c | 12 +++---- library.c | 32 +++++++++++++++++-- main.c | 4 +-- openconnect.h | 5 +-- 6 files changed, 44 insertions(+), 16 deletions(-) diff --git a/gpst.c b/gpst.c index f8143a68..d06210b6 100644 --- a/gpst.c +++ b/gpst.c @@ -1331,6 +1331,7 @@ int gpst_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable) vpninfo->quit_reason = "HIP check or report failed"; return ret; } + /* XX: no need to do_reconnect, since ESP doesn't need reconnection */ if (gpst_connect(vpninfo)) vpninfo->quit_reason = "GPST connect failed"; return 1; @@ -1349,7 +1350,7 @@ int gpst_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable) ret = ssl_reconnect(vpninfo); if (ret) { vpn_progress(vpninfo, PRG_ERR, _("Reconnect failed\n")); - vpninfo->quit_reason = "GPST reconnect failed"; + vpninfo->quit_reason = "GPST connect failed"; return ret; } if (vpninfo->proto->udp_setup) diff --git a/java/src/org/infradead/libopenconnect/LibOpenConnect.java b/java/src/org/infradead/libopenconnect/LibOpenConnect.java index bdf3d107..d55c7784 100644 --- a/java/src/org/infradead/libopenconnect/LibOpenConnect.java +++ b/java/src/org/infradead/libopenconnect/LibOpenConnect.java @@ -151,8 +151,8 @@ public synchronized native void setMobileInfo(String mobilePlatformVersion, public synchronized native int setAllowInsecureCrypto(boolean isEnabled); public synchronized native void setSystemTrust(boolean isEnabled); public synchronized native int setProtocol(String protocol); - public synchronized native void disableDTLS(); - public synchronized native void disableIPv6(); + public synchronized native int disableDTLS(); + public synchronized native int disableIPv6(); /* connection info */ diff --git a/jni.c b/jni.c index 6df1b6bb..3573d852 100644 --- a/jni.c +++ b/jni.c @@ -1001,24 +1001,24 @@ JNIEXPORT void JNICALL Java_org_infradead_libopenconnect_LibOpenConnect_resetSSL openconnect_reset_ssl(ctx->vpninfo); } -JNIEXPORT void JNICALL Java_org_infradead_libopenconnect_LibOpenConnect_disableIPv6( +JNIEXPORT int JNICALL Java_org_infradead_libopenconnect_LibOpenConnect_disableIPv6( JNIEnv *jenv, jobject jobj) { struct libctx *ctx = getctx(jenv, jobj); if (!ctx) - return; - openconnect_disable_ipv6(ctx->vpninfo); + return -EINVAL; + return openconnect_disable_ipv6(ctx->vpninfo); } -JNIEXPORT void JNICALL Java_org_infradead_libopenconnect_LibOpenConnect_disableDTLS( +JNIEXPORT int JNICALL Java_org_infradead_libopenconnect_LibOpenConnect_disableDTLS( JNIEnv *jenv, jobject jobj) { struct libctx *ctx = getctx(jenv, jobj); if (!ctx) - return; - openconnect_disable_dtls(ctx->vpninfo); + return -EINVAL; + return openconnect_disable_dtls(ctx->vpninfo); } JNIEXPORT void JNICALL Java_org_infradead_libopenconnect_LibOpenConnect_setCertExpiryWarning( diff --git a/library.c b/library.c index 77dc8deb..57a89512 100644 --- a/library.c +++ b/library.c @@ -552,14 +552,40 @@ void openconnect_set_xmlsha1(struct openconnect_info *vpninfo, memcpy(&vpninfo->xmlsha1, xmlsha1, size); } -void openconnect_disable_ipv6(struct openconnect_info *vpninfo) -{ +int openconnect_disable_ipv6(struct openconnect_info *vpninfo) +{ + /* This prevents disabling IPv6 when the connection is + * currently connected or has been connected previously. + * + * XX: It would be better to allow it when currently + * disconnected, but we currently have no way to indicate + * a state in which IP and routing configuration are + * unconfigured state. (Neither a closed TLS socket + * nor tunnel socket is a reliable indicator.) + */ + if (!vpninfo->disable_ipv6 + || vpninfo->ssl_times.last_tx != 0) + return -EINVAL; vpninfo->disable_ipv6 = 1; + return 0; } -void openconnect_disable_dtls(struct openconnect_info *vpninfo) +int openconnect_disable_dtls(struct openconnect_info *vpninfo) { + /* This disables DTLS or ESP. It is prevented when the + * connection is currently connected or has been + * connected previously. + * + * XX: It would be better to allow it when DTLS is not + * in use, but other than DTLS already being disabled, + * we currently do not have a reliable indicator of + * this. + */ + if (vpninfo->dtls_state != DTLS_DISABLED + || vpninfo->ssl_times.last_tx != 0) + return -EINVAL; vpninfo->dtls_state = DTLS_DISABLED; + return 0; } int openconnect_set_cafile(struct openconnect_info *vpninfo, const char *cafile) diff --git a/main.c b/main.c index 502bfc82..1a4c05b0 100644 --- a/main.c +++ b/main.c @@ -1737,7 +1737,7 @@ int main(int argc, char **argv) gai->value = gai->option + (ip - config_arg) + 1; break; case OPT_NO_DTLS: - vpninfo->dtls_state = DTLS_DISABLED; + openconnect_disable_dtls(vpninfo); break; case OPT_COOKIEONLY: cookieonly = 1; @@ -1867,7 +1867,7 @@ int main(int argc, char **argv) username = dup_config_arg(); break; case OPT_DISABLE_IPV6: - vpninfo->disable_ipv6 = 1; + openconnect_disable_ipv6(vpninfo); break; case 'Q': vpninfo->max_qlen = atol(config_arg); diff --git a/openconnect.h b/openconnect.h index 6921c39a..5abb7bb8 100644 --- a/openconnect.h +++ b/openconnect.h @@ -41,6 +41,7 @@ extern "C" { * - Add openconnect_set_allow_insecure_crypto() * - Add openconnect_get_auth_expiration() * - Add openconnect_disable_dtls() + * - Make openconnect_disable_ipv6() return int * * API version 5.6 (v8.06; 2020-03-31): * - Add openconnect_set_trojan_interval() @@ -550,8 +551,8 @@ const char *openconnect_get_cookie(struct openconnect_info *); int openconnect_set_cookie(struct openconnect_info *, const char *); void openconnect_clear_cookie(struct openconnect_info *); -void openconnect_disable_ipv6(struct openconnect_info *vpninfo); -void openconnect_disable_dtls(struct openconnect_info *vpninfo); +int openconnect_disable_ipv6(struct openconnect_info *vpninfo); +int openconnect_disable_dtls(struct openconnect_info *vpninfo); void openconnect_reset_ssl(struct openconnect_info *vpninfo); int openconnect_parse_url(struct openconnect_info *vpninfo, const char *url); void openconnect_set_cert_expiry_warning(struct openconnect_info *vpninfo,