Created
November 15, 2019 18:33
-
-
Save robbat2/ba6758d57c5571382c68f36585992b66 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From: Corey Wright <cwright@digitalocean.com> | |
Date: 2019/10/21 08:39 UTC | |
Subject: Combined HIP patch | |
Fixes: https://jira.internal.digitalocean.com/browse/SEC-2994 | |
Signed-off-by: Robin H. Johnson <rjohnson@digitalocean.com> | |
diff -urNpd openconnect-8.05~/gpst.c openconnect-8.05/gpst.c | |
--- openconnect-8.05~/gpst.c 2019-07-16 05:40:28.000000000 -0500 | |
+++ openconnect-8.05/gpst.c 2019-10-21 10:35:09.029687027 -0500 | |
@@ -603,6 +603,12 @@ static int gpst_parse_config_xml(struct | |
vpninfo->ssl_times.dpd = 10; | |
vpninfo->ssl_times.keepalive = vpninfo->esp_ssl_fallback = vpninfo->ssl_times.dpd; | |
+ /* Set 1-hour/3600-second HIP check (same as official client) unless | |
+ * overridden with --force-hip-check */ | |
+ if (!vpninfo->ssl_times.hip) | |
+ vpninfo->ssl_times.hip = 3600; | |
+ vpninfo->ssl_times.last_hip = time(NULL); | |
+ | |
free(s); | |
return 0; | |
} | |
@@ -1000,6 +1006,22 @@ static int run_hip_script(struct opencon | |
#endif /* !_WIN32 && !__native_client__ */ | |
} | |
+static int check_and_maybe_submit_hip_report(struct openconnect_info *vpninfo) | |
+{ | |
+ int ret; | |
+ | |
+ ret = check_or_submit_hip_report(vpninfo, NULL); | |
+ if (ret == -EAGAIN) { | |
+ vpn_progress(vpninfo, PRG_DEBUG, | |
+ _("Gateway says HIP report submission is needed.\n")); | |
+ ret = run_hip_script(vpninfo); | |
+ } else if (ret == 0) | |
+ vpn_progress(vpninfo, PRG_DEBUG, | |
+ _("Gateway says no HIP report submission is needed.\n")); | |
+ | |
+ return ret; | |
+} | |
+ | |
int gpst_setup(struct openconnect_info *vpninfo) | |
{ | |
int ret; | |
@@ -1014,16 +1036,9 @@ int gpst_setup(struct openconnect_info * | |
goto out; | |
/* Check HIP */ | |
- ret = check_or_submit_hip_report(vpninfo, NULL); | |
- if (ret == -EAGAIN) { | |
- vpn_progress(vpninfo, PRG_DEBUG, | |
- _("Gateway says HIP report submission is needed.\n")); | |
- ret = run_hip_script(vpninfo); | |
- if (ret != 0) | |
- goto out; | |
- } else if (ret == 0) | |
- vpn_progress(vpninfo, PRG_DEBUG, | |
- _("Gateway says no HIP report submission is needed.\n")); | |
+ ret = check_and_maybe_submit_hip_report(vpninfo); | |
+ if (ret) | |
+ goto out; | |
/* We do NOT actually start the HTTPS tunnel yet if we want to | |
* use ESP, because the ESP tunnel won't work if the HTTPS tunnel | |
@@ -1054,9 +1069,12 @@ int gpst_mainloop(struct openconnect_inf | |
vpninfo->dtls_state = DTLS_CONNECTED; | |
/* fall through */ | |
case DTLS_CONNECTED: | |
+ ret = keepalive_action(&vpninfo->ssl_times, timeout); | |
/* Rekey if needed */ | |
- if (keepalive_action(&vpninfo->ssl_times, timeout) == KA_REKEY) | |
+ if (ret == KA_REKEY) | |
goto do_rekey; | |
+ else if (ret == KA_HIP) | |
+ goto do_hip; | |
return 0; | |
case DTLS_SECRET: | |
case DTLS_SLEEPING: | |
@@ -1238,6 +1256,19 @@ int gpst_mainloop(struct openconnect_inf | |
vpninfo->current_ssl_pkt = (struct pkt *)&dpd_pkt; | |
goto handle_outgoing; | |
+ case KA_HIP: | |
+ do_hip: | |
+ vpn_progress(vpninfo, PRG_INFO, _("GlobalProtect HIP check due\n")); | |
+ ret = check_and_maybe_submit_hip_report(vpninfo); | |
+ /* Close HTTPS socket or server will probably close it before | |
+ we need it again, eg next HIP check, and then it'll just | |
+ blow up on us after we write to it, but can't read from it */ | |
+ openconnect_close_https(vpninfo, 0); | |
+ if (ret) { | |
+ vpn_progress(vpninfo, PRG_ERR, _("HIP check or report failed\n")); | |
+ vpninfo->quit_reason = "HIP check or report failed"; | |
+ return ret; | |
+ } | |
} | |
diff -urNpd openconnect-8.05~/libopenconnect.map.in openconnect-8.05/libopenconnect.map.in | |
--- openconnect-8.05~/libopenconnect.map.in 2018-12-21 06:20:31.000000000 -0600 | |
+++ openconnect-8.05/libopenconnect.map.in 2019-10-21 10:35:09.033687030 -0500 | |
@@ -103,6 +103,11 @@ OPENCONNECT_5_5 { | |
openconnect_set_version_string; | |
} OPENCONNECT_5_4; | |
+OPENCONNECT_5_6 { | |
+ global: | |
+ openconnect_set_hip_check; | |
+} OPENCONNECT_5_5; | |
+ | |
OPENCONNECT_PRIVATE { | |
global: @SYMVER_TIME@ @SYMVER_GETLINE@ @SYMVER_JAVA@ @SYMVER_ASPRINTF@ @SYMVER_VASPRINTF@ @SYMVER_WIN32_STRERROR@ | |
openconnect_fopen_utf8; | |
diff -urNpd openconnect-8.05~/library.c openconnect-8.05/library.c | |
--- openconnect-8.05~/library.c 2019-08-02 12:52:36.000000000 -0500 | |
+++ openconnect-8.05/library.c 2019-10-21 10:35:09.029687027 -0500 | |
@@ -577,6 +577,11 @@ void openconnect_set_dpd(struct openconn | |
vpninfo->dtls_times.dpd = vpninfo->ssl_times.dpd = 2; | |
} | |
+void openconnect_set_hip_check(struct openconnect_info *vpninfo, int seconds) | |
+{ | |
+ vpninfo->ssl_times.hip = seconds; | |
+} | |
+ | |
int openconnect_get_idle_timeout(struct openconnect_info *vpninfo) | |
{ | |
return vpninfo->idle_timeout; | |
diff -urNpd openconnect-8.05~/main.c openconnect-8.05/main.c | |
--- openconnect-8.05~/main.c 2019-05-18 12:51:27.000000000 -0500 | |
+++ openconnect-8.05/main.c 2019-10-21 10:35:09.033687030 -0500 | |
@@ -161,6 +161,7 @@ enum { | |
OPT_DTLS12_CIPHERS, | |
OPT_DUMP_HTTP, | |
OPT_FORCE_DPD, | |
+ OPT_FORCE_HIP_CHECK, | |
OPT_GNUTLS_DEBUG, | |
OPT_JUNIPER, | |
OPT_KEY_PASSWORD_FROM_FSID, | |
@@ -266,6 +267,7 @@ static const struct option long_options[ | |
OPTION("no-http-keepalive", 0, OPT_NO_HTTP_KEEPALIVE), | |
OPTION("no-cert-check", 0, OPT_NO_CERT_CHECK), | |
OPTION("force-dpd", 1, OPT_FORCE_DPD), | |
+ OPTION("force-hip-check", 1, OPT_FORCE_HIP_CHECK), | |
OPTION("non-inter", 0, OPT_NON_INTER), | |
OPTION("dtls-local-port", 1, OPT_DTLS_LOCAL_PORT), | |
OPTION("token-mode", 1, OPT_TOKEN_MODE), | |
@@ -900,6 +902,7 @@ static void usage(void) | |
printf("\n%s:\n", _("Server bugs")); | |
printf(" --no-http-keepalive %s\n", _("Disable HTTP connection re-use")); | |
printf(" --no-xmlpost %s\n", _("Do not attempt XML POST authentication")); | |
+ printf(" --force-hip-check=INTERVAL %s\n", _("Set HIP check interval in seconds")); | |
printf("\n"); | |
@@ -1447,6 +1450,9 @@ int main(int argc, char **argv) | |
case OPT_FORCE_DPD: | |
openconnect_set_dpd(vpninfo, atoi(config_arg)); | |
break; | |
+ case OPT_FORCE_HIP_CHECK: | |
+ openconnect_set_hip_check(vpninfo, atoi(config_arg)); | |
+ break; | |
case OPT_DTLS_LOCAL_PORT: | |
vpninfo->dtls_local_port = atoi(config_arg); | |
break; | |
diff -urNpd openconnect-8.05~/mainloop.c openconnect-8.05/mainloop.c | |
--- openconnect-8.05~/mainloop.c 2019-07-16 05:40:28.000000000 -0500 | |
+++ openconnect-8.05/mainloop.c 2019-10-21 10:33:47.917637304 -0500 | |
@@ -361,6 +361,12 @@ int keepalive_action(struct keepalive_in | |
return KA_REKEY; | |
} | |
+ if (ka->hip && | |
+ ka_check_deadline(timeout, now, ka->last_hip + ka->hip)) { | |
+ ka->last_hip = now; | |
+ return KA_HIP; | |
+ } | |
+ | |
/* DPD is bidirectional -- PKT 3 out, PKT 4 back */ | |
if (ka->dpd) { | |
time_t due = ka->last_rx + ka->dpd; | |
diff -urNpd openconnect-8.05~/openconnect.h openconnect-8.05/openconnect.h | |
--- openconnect-8.05~/openconnect.h 2019-09-11 18:31:04.000000000 -0500 | |
+++ openconnect-8.05/openconnect.h 2019-10-21 10:35:09.033687030 -0500 | |
@@ -33,9 +33,12 @@ extern "C" { | |
#endif | |
#define OPENCONNECT_API_VERSION_MAJOR 5 | |
-#define OPENCONNECT_API_VERSION_MINOR 5 | |
+#define OPENCONNECT_API_VERSION_MINOR 6 | |
/* | |
+ * API version 5.6 (v8.02; 2019-08-04): | |
+ * - Add openconnect_set_hip_check() | |
+ * | |
* API version 5.5 (v8.00; 2019-01-05): | |
* - add openconnect_set_version_string() | |
* - add openconnect_set_key_password() | |
@@ -521,6 +524,7 @@ int openconnect_set_key_password(struct | |
const char *openconnect_get_ifname(struct openconnect_info *); | |
void openconnect_set_reqmtu(struct openconnect_info *, int reqmtu); | |
void openconnect_set_dpd(struct openconnect_info *, int min_seconds); | |
+void openconnect_set_hip_check(struct openconnect_info *, int seconds); | |
int openconnect_get_idle_timeout(struct openconnect_info *); | |
/* The returned structures are owned by the library and may be freed/replaced | |
diff -urNpd openconnect-8.05~/openconnect-internal.h openconnect-8.05/openconnect-internal.h | |
--- openconnect-8.05~/openconnect-internal.h 2019-07-16 06:30:34.000000000 -0500 | |
+++ openconnect-8.05/openconnect-internal.h 2019-10-21 10:33:47.917637304 -0500 | |
@@ -163,6 +163,7 @@ struct pkt { | |
#define KA_DPD_DEAD 2 | |
#define KA_KEEPALIVE 3 | |
#define KA_REKEY 4 | |
+#define KA_HIP 5 | |
#define DTLS_NOSECRET 0 /* Random secret has not been generated yet */ | |
#define DTLS_SECRET 1 /* Secret is present, ready to attempt DTLS */ | |
@@ -191,10 +192,12 @@ struct keepalive_info { | |
int keepalive; | |
int rekey; | |
int rekey_method; | |
+ int hip; | |
time_t last_rekey; | |
time_t last_tx; | |
time_t last_rx; | |
time_t last_dpd; | |
+ time_t last_hip; | |
}; | |
struct pin_cache { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment