mirror of
https://github.com/OpenVPN/openvpn.git
synced 2025-05-09 05:31:05 +08:00
Fixed an issue where application payload transmissions on the
TLS control channel (such as AUTH_FAILED) that occur during or immediately after a TLS renegotiation might be dropped. Version 2.1.1n git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@6350 e7ae566f-a301-0410-adde-c780ea21d3b5
This commit is contained in:
parent
1400e1c156
commit
dc85dae67f
30
buffer.c
30
buffer.c
@ -896,8 +896,11 @@ buffer_list_new (const int max_size)
|
||||
void
|
||||
buffer_list_free (struct buffer_list *ol)
|
||||
{
|
||||
if (ol)
|
||||
{
|
||||
buffer_list_reset (ol);
|
||||
free (ol);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@ -924,9 +927,21 @@ buffer_list_reset (struct buffer_list *ol)
|
||||
void
|
||||
buffer_list_push (struct buffer_list *ol, const unsigned char *str)
|
||||
{
|
||||
if (!ol->max_size || ol->size < ol->max_size)
|
||||
if (str)
|
||||
{
|
||||
const size_t len = strlen ((const char *)str);
|
||||
struct buffer_entry *e = buffer_list_push_data (ol, str, len+1);
|
||||
if (e)
|
||||
e->buf.len = len; /* Don't count trailing '\0' as part of length */
|
||||
}
|
||||
}
|
||||
|
||||
struct buffer_entry *
|
||||
buffer_list_push_data (struct buffer_list *ol, const uint8_t *data, size_t size)
|
||||
{
|
||||
struct buffer_entry *e = NULL;
|
||||
if (data && (!ol->max_size || ol->size < ol->max_size))
|
||||
{
|
||||
struct buffer_entry *e;
|
||||
ALLOC_OBJ_CLEAR (e, struct buffer_entry);
|
||||
|
||||
++ol->size;
|
||||
@ -940,15 +955,18 @@ buffer_list_push (struct buffer_list *ol, const unsigned char *str)
|
||||
ASSERT (!ol->head);
|
||||
ol->head = e;
|
||||
}
|
||||
e->buf = string_alloc_buf ((const char *) str, NULL);
|
||||
e->buf = alloc_buf (size);
|
||||
memcpy (e->buf.data, data, size);
|
||||
e->buf.len = (int)size;
|
||||
ol->tail = e;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
struct buffer *
|
||||
buffer_list_peek (struct buffer_list *ol)
|
||||
{
|
||||
if (ol->head)
|
||||
if (ol && ol->head)
|
||||
return &ol->head->buf;
|
||||
else
|
||||
return NULL;
|
||||
@ -993,10 +1011,10 @@ buffer_list_aggregate (struct buffer_list *bl, const size_t max)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
buffer_list_pop (struct buffer_list *ol)
|
||||
{
|
||||
if (ol->head)
|
||||
if (ol && ol->head)
|
||||
{
|
||||
struct buffer_entry *e = ol->head->next;
|
||||
free_buf (&ol->head->buf);
|
||||
|
2
buffer.h
2
buffer.h
@ -851,8 +851,10 @@ bool buffer_list_defined (const struct buffer_list *ol);
|
||||
void buffer_list_reset (struct buffer_list *ol);
|
||||
|
||||
void buffer_list_push (struct buffer_list *ol, const unsigned char *str);
|
||||
struct buffer_entry *buffer_list_push_data (struct buffer_list *ol, const uint8_t *data, size_t size);
|
||||
struct buffer *buffer_list_peek (struct buffer_list *ol);
|
||||
void buffer_list_advance (struct buffer_list *ol, int n);
|
||||
void buffer_list_pop (struct buffer_list *ol);
|
||||
|
||||
void buffer_list_aggregate (struct buffer_list *bl, const size_t max);
|
||||
|
||||
|
22
ssl.c
22
ssl.c
@ -2266,6 +2266,7 @@ key_state_free (struct key_state *ks, bool clear)
|
||||
free_buf (&ks->plaintext_read_buf);
|
||||
free_buf (&ks->plaintext_write_buf);
|
||||
free_buf (&ks->ack_write_buf);
|
||||
buffer_list_free(ks->paybuf);
|
||||
|
||||
if (ks->send_reliable)
|
||||
{
|
||||
@ -3064,6 +3065,17 @@ key_source2_read (struct key_source2 *k2,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
flush_payload_buffer (struct tls_multi *multi, struct key_state *ks)
|
||||
{
|
||||
struct buffer *b;
|
||||
while ((b = buffer_list_peek (ks->paybuf)))
|
||||
{
|
||||
key_state_write_plaintext_const (multi, ks, b->data, b->len);
|
||||
buffer_list_pop (ks->paybuf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Macros for key_state_soft_reset & tls_process
|
||||
*/
|
||||
@ -3978,6 +3990,9 @@ tls_process (struct tls_multi *multi,
|
||||
/* Set outgoing address for data channel packets */
|
||||
link_socket_set_outgoing_addr (NULL, to_link_socket_info, &ks->remote_addr, session->common_name, session->opt->es);
|
||||
|
||||
/* Flush any payload packets that were buffered before our state transitioned to S_ACTIVE */
|
||||
flush_payload_buffer (multi, ks);
|
||||
|
||||
#ifdef MEASURE_TLS_HANDSHAKE_STATS
|
||||
show_tls_performance_stats();
|
||||
#endif
|
||||
@ -5077,6 +5092,13 @@ tls_send_payload (struct tls_multi *multi,
|
||||
if (key_state_write_plaintext_const (multi, ks, data, size) == 1)
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ks->paybuf)
|
||||
ks->paybuf = buffer_list_new (0);
|
||||
buffer_list_push_data (ks->paybuf, data, (size_t)size);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
ERR_clear_error ();
|
||||
|
||||
|
2
ssl.h
2
ssl.h
@ -376,6 +376,8 @@ struct key_state
|
||||
struct reliable *rec_reliable; /* order incoming ciphertext packets before we pass to TLS */
|
||||
struct reliable_ack *rec_ack; /* buffers all packet IDs we want to ACK back to sender */
|
||||
|
||||
struct buffer_list *paybuf;
|
||||
|
||||
int n_bytes; /* how many bytes sent/recvd since last key exchange */
|
||||
int n_packets; /* how many packets sent/recvd since last key exchange */
|
||||
|
||||
|
@ -531,11 +531,9 @@ socket_defined (const socket_descriptor_t sd)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Don't compile the struct buffer_list code unless something needs it
|
||||
* Compile the struct buffer_list code
|
||||
*/
|
||||
#if defined(ENABLE_MANAGEMENT) || defined(ENABLE_PF)
|
||||
#define ENABLE_BUFFER_LIST
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Do we have pthread capability?
|
||||
|
@ -1,5 +1,5 @@
|
||||
dnl define the OpenVPN version
|
||||
define(PRODUCT_VERSION,[2.1.1m])
|
||||
define(PRODUCT_VERSION,[2.1.1n])
|
||||
dnl define the TAP version
|
||||
define(PRODUCT_TAP_ID,[tap0901])
|
||||
define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9])
|
||||
|
Loading…
x
Reference in New Issue
Block a user