Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Move DTLS methods into struct vpn_proto
This also slightly cleans up the way we disable DTLS.

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Jan 26, 2015
1 parent c5c0499 commit 9831d26
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 42 deletions.
30 changes: 16 additions & 14 deletions cstp.c
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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);
Expand Down
19 changes: 4 additions & 15 deletions dtls.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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
23 changes: 22 additions & 1 deletion library.c
Expand Up @@ -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;

Expand All @@ -102,6 +110,18 @@ struct openconnect_info *openconnect_vpninfo_new(const char *useragent,
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)
{
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions main.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 3 additions & 5 deletions mainloop.c
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
Expand Down
23 changes: 19 additions & 4 deletions openconnect-internal.h
Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 9831d26

Please sign in to comment.