Commit 75fb44de authored by David Woodhouse's avatar David Woodhouse

Tell server when ESP is running

Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 0e74951d
......@@ -156,12 +156,35 @@ int print_esp_keys(struct openconnect_info *vpninfo, const char *name, struct es
return 0;
}
int esp_setup(struct openconnect_info *vpninfo, int dtls_attempt_period)
static int esp_send_probes(struct openconnect_info *vpninfo)
{
int fd;
struct pkt *pkt;
int pktlen;
pkt = malloc(sizeof(*pkt) + 1 + vpninfo->pkt_trailer);
if (!pkt)
return -ENOMEM;
pkt->len = 1;
pkt->data[0] = 0;
pktlen = encrypt_esp_packet(vpninfo, pkt);
send(vpninfo->dtls_fd, &pkt->esp, pktlen, 0);
pkt->len = 1;
pkt->data[0] = 0;
pktlen = encrypt_esp_packet(vpninfo, pkt);
send(vpninfo->dtls_fd, &pkt->esp, pktlen, 0);
free(pkt);
time(&vpninfo->new_dtls_started);
return 0;
};
int esp_setup(struct openconnect_info *vpninfo, int dtls_attempt_period)
{
int fd;
if (vpninfo->dtls_state == DTLS_DISABLED ||
vpninfo->dtls_state == DTLS_NOSECRET)
return -EINVAL;
......@@ -170,34 +193,17 @@ int esp_setup(struct openconnect_info *vpninfo, int dtls_attempt_period)
if (fd < 0)
return fd;
pkt = malloc(sizeof(*pkt) + 1 + vpninfo->pkt_trailer);
if (!pkt) {
closesocket(fd);
return -ENOMEM;
}
print_esp_keys(vpninfo, _("incoming"), &vpninfo->esp_in);
print_esp_keys(vpninfo, _("outgoing"), &vpninfo->esp_out);
/* We are not connected until we get an ESP packet back */
vpninfo->dtls_state = DTLS_CONNECTING;
vpninfo->dtls_state = DTLS_SLEEPING;
vpninfo->dtls_fd = fd;
monitor_fd_new(vpninfo, dtls);
monitor_read_fd(vpninfo, dtls);
monitor_except_fd(vpninfo, dtls);
pkt->len = 1;
pkt->data[0] = 0;
pktlen = encrypt_esp_packet(vpninfo, pkt);
send(fd, &pkt->esp, pktlen, 0);
pkt->len = 1;
pkt->data[0] = 0;
pktlen = encrypt_esp_packet(vpninfo, pkt);
send(fd, &pkt->esp, pktlen, 0);
free(pkt);
time(&vpninfo->new_dtls_started);
esp_send_probes(vpninfo);
return 0;
}
......@@ -254,9 +260,11 @@ int esp_mainloop(struct openconnect_info *vpninfo, int *timeout)
pkt->len = len - 2 - pkt->data[len - 2];
if (pkt->len == 1 && pkt->data[0] == 0) {
vpn_progress(vpninfo, PRG_INFO,
_("ESP session established with server\n"));
vpninfo->dtls_state = DTLS_CONNECTED;
if (vpninfo->dtls_state == DTLS_SLEEPING) {
vpn_progress(vpninfo, PRG_INFO,
_("ESP session established with server\n"));
vpninfo->dtls_state = DTLS_CONNECTING;
}
continue;
}
queue_packet(&vpninfo->incoming_queue, pkt);
......
......@@ -908,6 +908,20 @@ static const unsigned char esp_kmp_part2[] = {
/* And now 0x40 bytes of random secret for encryption and HMAC key */
static const struct pkt esp_enable_pkt = {
.oncp_hdr = {
0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0d
},
.data = {
0x00, 0x06, 0x00, 0x00, 0x00, 0x07, /* Group 6, len 7 */
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, /* Attr 1, len 1 */
0x01
},
.len = 13
};
int oncp_connect(struct openconnect_info *vpninfo)
{
int ret, ofs, kmp, kmpend, kmplen, attr, attrlen, group, grouplen, groupend;
......@@ -1447,13 +1461,14 @@ int oncp_mainloop(struct openconnect_info *vpninfo, int *timeout)
/* Don't free the 'special' packets */
if (vpninfo->current_ssl_pkt == vpninfo->deflate_pkt)
free(vpninfo->pending_deflated_pkt);
else
#if 0 /* No DPD or keepalive for Juniper yet */
if (vpninfo->current_ssl_pkt != &dpd_pkt &&
vpninfo->current_ssl_pkt != &dpd_resp_pkt &&
vpninfo->current_ssl_pkt != &keepalive_pkt)
#endif
else if (vpninfo->current_ssl_pkt == &esp_enable_pkt) {
/* If we sent the special ESP enable packet, ESP
* is now enabled. And we don't need to free it. */
if (vpninfo->dtls_state == DTLS_CONNECTING)
vpninfo->dtls_state = DTLS_CONNECTED;
} else {
free(vpninfo->current_ssl_pkt);
}
vpninfo->current_ssl_pkt = NULL;
}
......@@ -1528,6 +1543,10 @@ int oncp_mainloop(struct openconnect_info *vpninfo, int *timeout)
}
#endif
if (vpninfo->dtls_state == DTLS_CONNECTING) {
vpninfo->current_ssl_pkt = (struct pkt *)&esp_enable_pkt;
goto handle_outgoing;
}
/* Service outgoing packet queue, if no DTLS */
while (vpninfo->dtls_state != DTLS_CONNECTED && vpninfo->outgoing_queue) {
struct pkt *this = vpninfo->outgoing_queue;
......
......@@ -155,9 +155,9 @@ struct pkt {
#define DTLS_NOSECRET 0
#define DTLS_SECRET 1
#define DTLS_DISABLED 2
#define DTLS_SLEEPING 3
#define DTLS_CONNECTING 4
#define DTLS_CONNECTED 5
#define DTLS_SLEEPING 3 /* For ESP, sometimes sending probes */
#define DTLS_CONNECTING 4 /* ESP probe received; must tell server */
#define DTLS_CONNECTED 5 /* Server informed and should be sending ESP */
#define COMPR_DEFLATE (1<<0)
#define COMPR_LZS (1<<1)
......
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