From 95654f4fe2bc8d3276563b5d115ff75a6e80455d Mon Sep 17 00:00:00 2001 From: Daniel Lenski Date: Wed, 22 May 2019 13:14:03 -0700 Subject: [PATCH] factor out check_address_sanity() from gpst.c and cstp.c, and use it in oncp.c and pulse.c as well Suggested by David Woodhouse: https://gitlab.com/openconnect/openconnect/merge_requests/35#note_169620281 Signed-off-by: Daniel Lenski --- cstp.c | 75 +++++++++++++++++++++++------------------- gpst.c | 36 ++------------------ oncp.c | 7 ++-- openconnect-internal.h | 1 + pulse.c | 10 +++--- 5 files changed, 55 insertions(+), 74 deletions(-) diff --git a/cstp.c b/cstp.c index e67144f4..b9d8251c 100644 --- a/cstp.c +++ b/cstp.c @@ -211,6 +211,44 @@ static int parse_hex_val(const char *str, unsigned char *storage, unsigned int m return len/2; } +int check_address_sanity(struct openconnect_info *vpninfo, const char *old_addr, const char *old_netmask, const char *old_addr6, const char *old_netmask6) +{ + if (old_addr) { + if (!vpninfo->ip_info.addr || strcmp(old_addr, vpninfo->ip_info.addr)) { + vpn_progress(vpninfo, PRG_ERR, + _("Reconnect gave different Legacy IP address (%s != %s)\n"), + vpninfo->ip_info.addr, old_addr); + /* EPERM means that the retry loop will abort and won't keep trying. */ + return -EPERM; + } + } + if (old_netmask) { + if (!vpninfo->ip_info.netmask || strcmp(old_netmask, vpninfo->ip_info.netmask)) { + vpn_progress(vpninfo, PRG_ERR, + _("Reconnect gave different Legacy IP netmask (%s != %s)\n"), + vpninfo->ip_info.netmask, old_netmask); + return -EPERM; + } + } + if (old_addr6) { + if (!vpninfo->ip_info.addr6 || strcmp(old_addr6, vpninfo->ip_info.addr6)) { + vpn_progress(vpninfo, PRG_ERR, + _("Reconnect gave different IPv6 address (%s != %s)\n"), + vpninfo->ip_info.addr6, old_addr6); + return -EPERM; + } + } + if (old_netmask6) { + if (!vpninfo->ip_info.netmask6 || strcmp(old_netmask6, vpninfo->ip_info.netmask6)) { + vpn_progress(vpninfo, PRG_ERR, + _("Reconnect gave different IPv6 netmask (%s != %s)\n"), + vpninfo->ip_info.netmask6, old_netmask6); + return -EPERM; + } + } + return 0; +} + static int start_cstp_connection(struct openconnect_info *vpninfo) { struct oc_text_buf *reqbuf; @@ -609,39 +647,10 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) _("IPv6 configuration received but MTU %d is too small.\n"), mtu); } - if (old_addr) { - if (!vpninfo->ip_info.addr || strcmp(old_addr, vpninfo->ip_info.addr)) { - vpn_progress(vpninfo, PRG_ERR, - _("Reconnect gave different Legacy IP address (%s != %s)\n"), - vpninfo->ip_info.addr, old_addr); - /* EPERM means that the retry loop will abort and won't keep trying. */ - return -EPERM; - } - } - if (old_netmask) { - if (!vpninfo->ip_info.netmask || strcmp(old_netmask, vpninfo->ip_info.netmask)) { - vpn_progress(vpninfo, PRG_ERR, - _("Reconnect gave different Legacy IP netmask (%s != %s)\n"), - vpninfo->ip_info.netmask, old_netmask); - return -EPERM; - } - } - if (old_addr6) { - if (!vpninfo->ip_info.addr6 || strcmp(old_addr6, vpninfo->ip_info.addr6)) { - vpn_progress(vpninfo, PRG_ERR, - _("Reconnect gave different IPv6 address (%s != %s)\n"), - vpninfo->ip_info.addr6, old_addr6); - return -EPERM; - } - } - if (old_netmask6) { - if (!vpninfo->ip_info.netmask6 || strcmp(old_netmask6, vpninfo->ip_info.netmask6)) { - vpn_progress(vpninfo, PRG_ERR, - _("Reconnect gave different IPv6 netmask (%s != %s)\n"), - vpninfo->ip_info.netmask6, old_netmask6); - return -EPERM; - } - } + + i = check_address_sanity(vpninfo, old_addr, old_netmask, old_addr6, old_netmask6); + if (i) + return i; free_optlist(old_dtls_opts); free_optlist(old_cstp_opts); diff --git a/gpst.c b/gpst.c index b437a60c..feee18ad 100644 --- a/gpst.c +++ b/gpst.c @@ -674,40 +674,8 @@ static int gpst_get_config(struct openconnect_info *vpninfo) result = -EINVAL; goto out; } - if (old_addr) { - if (!vpninfo->ip_info.addr || strcmp(old_addr, vpninfo->ip_info.addr)) { - vpn_progress(vpninfo, PRG_ERR, - _("Reconnect gave different Legacy IP address (%s != %s)\n"), - vpninfo->ip_info.addr, old_addr); - result = -EPERM; - goto out; - } - } - if (old_netmask) { - if (!vpninfo->ip_info.netmask || strcmp(old_netmask, vpninfo->ip_info.netmask)) { - vpn_progress(vpninfo, PRG_ERR, - _("Reconnect gave different Legacy IP netmask (%s != %s)\n"), - vpninfo->ip_info.netmask, old_netmask); - result = -EPERM; - goto out; - } - } - if (old_addr6) { - if (!vpninfo->ip_info.addr6 || strcmp(old_addr6, vpninfo->ip_info.addr6)) { - vpn_progress(vpninfo, PRG_ERR, - _("Reconnect gave different IPv6 address (%s != %s)\n"), - vpninfo->ip_info.addr6, old_addr6); - return -EINVAL; - } - } - if (old_netmask6) { - if (!vpninfo->ip_info.netmask6 || strcmp(old_netmask6, vpninfo->ip_info.netmask6)) { - vpn_progress(vpninfo, PRG_ERR, - _("Reconnect gave different IPv6 netmask (%s != %s)\n"), - vpninfo->ip_info.netmask6, old_netmask6); - return -EINVAL; - } - } + + result = check_address_sanity(vpninfo, old_addr, old_netmask, old_addr6, old_netmask6); out: free_optlist(old_cstp_opts); diff --git a/oncp.c b/oncp.c index 243143da..171fb8c7 100644 --- a/oncp.c +++ b/oncp.c @@ -544,9 +544,7 @@ int oncp_connect(struct openconnect_info *vpninfo) int ret, len, kmp, kmplen, group, check_len; struct oc_text_buf *reqbuf; unsigned char bytes[65536]; - - /* XXX: We should do what cstp_connect() does to check that configuration - hasn't changed on a reconnect. */ + const char *old_addr = vpninfo->ip_info.addr, *old_netmask = vpninfo->ip_info.netmask; if (!vpninfo->cookies) { ret = parse_cookie(vpninfo); @@ -789,6 +787,9 @@ int oncp_connect(struct openconnect_info *vpninfo) _("Short write in oNCP negotiation\n")); ret = -EIO; } + + ret = check_address_sanity(vpninfo, old_addr, old_netmask, NULL, NULL); + out: if (ret) openconnect_close_https(vpninfo, 0); diff --git a/openconnect-internal.h b/openconnect-internal.h index 92edf763..9ff85150 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -892,6 +892,7 @@ char *openconnect_bin2hex(const char *prefix, const uint8_t *data, unsigned len) char *openconnect_bin2base64(const char *prefix, const uint8_t *data, unsigned len); /* cstp.c */ +int check_address_sanity(struct openconnect_info *vpninfo, const char *old_addr, const char *old_netmask, const char *old_addr6, const char *old_netmask6); void cstp_common_headers(struct openconnect_info *vpninfo, struct oc_text_buf *buf); int cstp_connect(struct openconnect_info *vpninfo); int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable); diff --git a/pulse.c b/pulse.c index c1ca5d16..067edbd3 100644 --- a/pulse.c +++ b/pulse.c @@ -1382,9 +1382,6 @@ static int pulse_authenticate(struct openconnect_info *vpninfo, int connecting) char *user2_prompt = NULL, *pass2_prompt = NULL; int prompt_flags = PROMPT_PRIMARY | PROMPT_USERNAME | PROMPT_PASSWORD; - /* XXX: We should do what cstp_connect() does to check that configuration - hasn't changed on a reconnect. */ - ret = openconnect_open_https(vpninfo); if (ret) return ret; @@ -2290,6 +2287,10 @@ static int handle_main_config_packet(struct openconnect_info *vpninfo, int routes_len = 0; int l; unsigned char *p; + const char *old_addr = vpninfo->ip_info.addr; + const char *old_netmask = vpninfo->ip_info.netmask; + const char *old_addr6 = vpninfo->ip_info.addr6; + const char *old_netmask6 = vpninfo->ip_info.netmask6; /* First part of header, similar to ESP, has already been checked */ if (len < 0x31 || @@ -2393,7 +2394,8 @@ static int handle_main_config_packet(struct openconnect_info *vpninfo, if (l && l < 4) goto bad_config; } - return 0; + + return check_address_sanity(vpninfo, old_addr, old_netmask, old_addr6, old_netmask6); } /* Example ESP config packet: -- 2.49.0