Commit 9831d261 authored by David Woodhouse's avatar David Woodhouse

Move DTLS methods into struct vpn_proto

This also slightly cleans up the way we disable DTLS.
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent c5c04993
......@@ -222,20 +222,22 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
vpninfo->disable_ipv6 ? "IPv4" : "IPv6,IPv4");
if (!vpninfo->disable_ipv6)
buf_append(reqbuf, "X-CSTP-Full-IPv6-Capability: true\r\n");
buf_append(reqbuf, "X-DTLS-Master-Secret: ");
for (i = 0; i < sizeof(vpninfo->dtls_secret); i++) {
buf_append(reqbuf, "%02X", vpninfo->dtls_secret[i]);
dtls_secret_set |= vpninfo->dtls_secret[i];
}
if (!dtls_secret_set) {
vpn_progress(vpninfo, PRG_ERR,
_("CRITICAL ERROR: DTLS master secret is uninitialised. Please report this.\n"));
return -EINVAL;
}
buf_append(reqbuf, "\r\nX-DTLS-CipherSuite: %s\r\n",
vpninfo->dtls_ciphers ? : DEFAULT_CIPHER_LIST);
if (vpninfo->dtls_state != DTLS_DISABLED) {
buf_append(reqbuf, "X-DTLS-Master-Secret: ");
for (i = 0; i < sizeof(vpninfo->dtls_secret); i++) {
buf_append(reqbuf, "%02X", vpninfo->dtls_secret[i]);
dtls_secret_set |= vpninfo->dtls_secret[i];
}
if (!dtls_secret_set) {
vpn_progress(vpninfo, PRG_ERR,
_("CRITICAL ERROR: DTLS master secret is uninitialised. Please report this.\n"));
return -EINVAL;
}
buf_append(reqbuf, "\r\nX-DTLS-CipherSuite: %s\r\n",
vpninfo->dtls_ciphers ? : DEFAULT_CIPHER_LIST);
append_compr_types(reqbuf, "DTLS", vpninfo->req_compr & ~COMPR_DEFLATE);
append_compr_types(reqbuf, "DTLS", vpninfo->req_compr & ~COMPR_DEFLATE);
}
buf_append(reqbuf, "\r\n");
if (buf_error(reqbuf)) {
......@@ -586,7 +588,7 @@ int openconnect_make_cstp_connection(struct openconnect_info *vpninfo)
if (openconnect_random(vpninfo->dtls_secret, sizeof(vpninfo->dtls_secret)))
return -EINVAL;
/* The application will later call openconnect_setup_dtls() */
vpninfo->dtls_state = DTLS_DISABLED;
vpninfo->dtls_state = DTLS_SECRET;
}
ret = openconnect_open_https(vpninfo);
......
......@@ -593,11 +593,14 @@ static int dtls_reconnect(struct openconnect_info *vpninfo)
return connect_dtls_socket(vpninfo);
}
int openconnect_setup_dtls(struct openconnect_info *vpninfo, int dtls_attempt_period)
int dtls_setup(struct openconnect_info *vpninfo, int dtls_attempt_period)
{
struct oc_vpn_option *dtls_opt = vpninfo->dtls_options;
int dtls_port = 0;
if (vpninfo->dtls_state == DTLS_DISABLED)
return -EINVAL;
vpninfo->dtls_attempt_period = dtls_attempt_period;
if (!dtls_attempt_period)
return 0;
......@@ -918,18 +921,4 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
}
#else /* !HAVE_DTLS */
#warning Your SSL library does not seem to support Cisco DTLS compatibility
int openconnect_setup_dtls(struct openconnect_info *vpninfo, int dtls_attempt_period)
{
vpn_progress(vpninfo, PRG_ERR,
_("Built against SSL library with no Cisco DTLS support\n"));
return -EINVAL;
}
void dtls_close(struct openconnect_info *vpninfo)
{
}
void dtls_shutdown(struct openconnect_info *vpninfo)
{
}
#endif
......@@ -92,6 +92,14 @@ struct openconnect_info *openconnect_vpninfo_new(const char *useragent,
#endif
vpninfo->proto.vpn_close_session = cstp_bye;
#ifdef HAVE_DTLS
vpninfo->proto.udp_setup = dtls_setup;
vpninfo->proto.udp_mainloop = dtls_mainloop;
vpninfo->proto.udp_close = dtls_close;
vpninfo->proto.udp_shutdown = dtls_shutdown;
#else
vpninfo->dtls_state = DTLS_DISABLED;
#endif
return vpninfo;
......@@ -102,6 +110,18 @@ err:
return NULL;
}
int openconnect_setup_dtls(struct openconnect_info *vpninfo,
int attempt_period)
{
if (vpninfo->proto.udp_setup)
return vpninfo->proto.udp_setup(vpninfo, attempt_period);
vpn_progress(vpninfo, PRG_ERR,
_("Built against SSL library with no Cisco DTLS support\n"));
return -EINVAL;
}
int openconnect_set_reported_os(struct openconnect_info *vpninfo,
const char *os)
{
......@@ -158,7 +178,8 @@ static void free_optlist(struct oc_vpn_option *opt)
void openconnect_vpninfo_free(struct openconnect_info *vpninfo)
{
openconnect_close_https(vpninfo, 1);
dtls_shutdown(vpninfo);
if (vpninfo->proto.udp_shutdown)
vpninfo->proto.udp_shutdown(vpninfo);
if (vpninfo->cmd_fd_write != -1) {
closesocket(vpninfo->cmd_fd);
closesocket(vpninfo->cmd_fd_write);
......
......@@ -940,7 +940,6 @@ int main(int argc, char **argv)
int autoproxy = 0;
int opt;
char *pidfile = NULL;
int use_dtls = 1;
FILE *fp = NULL;
char *config_arg;
char *config_filename;
......@@ -1098,7 +1097,7 @@ int main(int argc, char **argv)
openconnect_set_system_trust(vpninfo, 0);
break;
case OPT_NO_DTLS:
use_dtls = 0;
vpninfo->dtls_state = DTLS_DISABLED;
break;
case OPT_COOKIEONLY:
cookieonly = 1;
......@@ -1436,7 +1435,8 @@ int main(int argc, char **argv)
}
#endif
if (use_dtls && openconnect_setup_dtls(vpninfo, 60))
if (vpninfo->dtls_state != DTLS_DISABLED &&
openconnect_setup_dtls(vpninfo, 60))
fprintf(stderr, _("Set up DTLS failed; using SSL instead\n"));
openconnect_get_ip_info(vpninfo, &ip_info, NULL, NULL);
......
......@@ -138,14 +138,12 @@ int openconnect_mainloop(struct openconnect_info *vpninfo,
fd_set rfds, wfds, efds;
#endif
#ifdef HAVE_DTLS
if (vpninfo->dtls_state != DTLS_DISABLED) {
ret = dtls_mainloop(vpninfo, &timeout);
if (vpninfo->dtls_state > DTLS_DISABLED) {
ret = vpninfo->proto.udp_mainloop(vpninfo, &timeout);
if (vpninfo->quit_reason)
break;
did_work += ret;
}
#endif
ret = cstp_mainloop(vpninfo, &timeout);
if (vpninfo->quit_reason)
......@@ -173,7 +171,7 @@ int openconnect_mainloop(struct openconnect_info *vpninfo,
openconnect_mainloop() again */
openconnect_close_https(vpninfo, 0);
if (vpninfo->dtls_state != DTLS_DISABLED) {
dtls_close(vpninfo);
vpninfo->proto.udp_close(vpninfo);
vpninfo->dtls_state = DTLS_SLEEPING;
vpninfo->new_dtls_started = 0;
}
......
......@@ -135,10 +135,11 @@ struct pkt {
#define KA_REKEY 4
#define DTLS_NOSECRET 0
#define DTLS_DISABLED 1
#define DTLS_SLEEPING 2
#define DTLS_CONNECTING 3
#define DTLS_CONNECTED 4
#define DTLS_SECRET 1
#define DTLS_DISABLED 2
#define DTLS_SLEEPING 3
#define DTLS_CONNECTING 4
#define DTLS_CONNECTED 5
#define COMPR_DEFLATE (1<<0)
#define COMPR_LZS (1<<1)
......@@ -203,6 +204,19 @@ struct proxy_auth_state {
struct vpn_proto {
int (*vpn_close_session)(struct openconnect_info *vpninfo, const char *reason);
/* Set up the UDP (DTLS) connection. Doesn't actually *start* it. */
int (*udp_setup)(struct openconnect_info *vpninfo, int attempt_period);
/* This will actually complete the UDP connection setup/handshake on the wire,
as well as transporting packets */
int (*udp_mainloop)(struct openconnect_info *vpninfo, int *timeout);
/* Close the connection but leave the session setup so it restarts */
void (*udp_close)(struct openconnect_info *vpninfo);
/* Close and destroy the (UDP) session */
void (*udp_shutdown)(struct openconnect_info *vpninfo);
};
struct openconnect_info {
......@@ -634,6 +648,7 @@ intptr_t os_setup_tun(struct openconnect_info *vpninfo);
/* dtls.c */
unsigned char unhex(const char *data);
int dtls_setup(struct openconnect_info *vpninfo, int dtls_attempt_period);
int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout);
int dtls_try_handshake(struct openconnect_info *vpninfo);
int connect_dtls_socket(struct openconnect_info *vpninfo);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment