Starting from
https://github.com/OpenVPN/openvpn/commit/3a5a46cf2b7f6a8b8520c2513a8054deb48bfcbe,
we add peer-id and cipher values to context->options->push_list instead of
adding those directly
to buf (as done for client-specific values, like ifconfig). Since push_list is
per child context,
when options are added and context is reused - we got duplicates.
Fixed by adding options to buffer, as it was done previously.
Signed-off-by: Lev Stipakov
---
src/openvpn/push.c | 83 +++---
1 file changed, 22 insertions(+), 61 deletions(-)
diff --git a/src/openvpn/push.c b/src/openvpn/push.c
index a1b999e..5220bf0 100644
--- a/src/openvpn/push.c
+++ b/src/openvpn/push.c
@@ -40,30 +40,6 @@
#if P2MP
-/**
- * Add an option to the push list by providing a format string.
- *
- * The string added to the push options is allocated in o->gc, so the caller
- * does not have to preserve anything.
- *
- * @param oThe current connection's options
- * @param msglevel The message level to use when printing errors
- * @param fmt Format string for the option
- * @param ... Format string arguments
- *
- * @return true on success, false on failure.
- */
-static bool push_option_fmt(struct options *o, int msglevel,
-const char *fmt, ...)
-#ifdef __GNUC__
-#if __USE_MINGW_ANSI_STDIO
-__attribute__ ((format (gnu_printf, 3, 4)))
-#else
-__attribute__ ((format (__printf__, 3, 4)))
-#endif
-#endif
-;
-
/*
* Auth username/password
*
@@ -293,31 +269,31 @@ send_push_request (struct context *c)
#if P2MP_SERVER
/**
- * Prepare push options, based on local options and available peer info.
+ * Add peer specific options, based on local options and peer info.
*
- * @param options Connection options
* @param tls_multiTLS state structure for the current tunnel
+ * @param options Connection options
+ * @param buf buffer to where options are added
*
- * @return true on success, false on failure.
*/
-static bool
-prepare_push_reply (struct options *o, struct tls_multi *tls_multi)
+static void
+add_peer_specific_opts (struct tls_multi *tls_multi, struct options *o, struct
buffer *buf)
{
- const char *optstr = NULL;
const char * const peer_info = tls_multi->peer_info;
-
+ const char *optstr = NULL;
+
/* Send peer-id if client supports it */
- optstr = peer_info ? strstr(peer_info, "IV_PROTO=") : NULL;
+ optstr = peer_info ? strstr (peer_info, "IV_PROTO=") : NULL;
if (optstr)
-{
- int proto = 0;
- int r = sscanf(optstr, "IV_PROTO=%d", &proto);
- if ((r == 1) && (proto >= 2))
- {
- push_option_fmt(o, M_USAGE, "peer-id %d", tls_multi->peer_id);
- }
-}
-
+ {
+int proto = 0;
+int r = sscanf (optstr, "IV_PROTO=%d", &proto);
+if ((r == 1) && (proto >= 2))
+ {
+ buf_printf (buf, ",peer-id %d", tls_multi->peer_id);
+ }
+ }
+
/* Push cipher if client supports Negotiable Crypto Parameters */
if (tls_peer_info_ncp_ver (peer_info) >= 2 && o->ncp_enabled)
{
@@ -335,12 +311,11 @@ prepare_push_reply (struct options *o, struct tls_multi
*tls_multi)
{
/* Push the first cipher from --ncp-ciphers to the client.
* TODO: actual negotiation, instead of server dictatorship. */
- char *push_cipher = string_alloc(o->ncp_ciphers, &o->gc);
+ char *push_cipher = string_alloc (o->ncp_ciphers, &o->gc);
o->ciphername = strtok (push_cipher, ":");
- push_option_fmt(o, M_USAGE, "cipher %s", o->ciphername);
+ buf_printf (buf, ",cipher %s", o->ciphername);
}
}
- return true;
}
static bool
@@ -414,6 +389,8 @@ send_push_reply (struct context *c)
if (multi_push)
buf_printf (&buf, ",push-continuation 1");
+ add_peer_specific_opts (c->c2.tls_multi, &c->options, &buf);
+
if (BLEN (&buf) > sizeof(cmd)-1)
{
const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
@@ -501,21 +478,6 @@ push_options (struct options *o, char **p, int msglevel,
struct gc_arena *gc)
push_option (o, opt, msglevel);
}
-static bool push_option_fmt(struct options *o, int msglevel,
-const char *format, ...)
-{
- va_list arglist;
- char tmp[256] = {0};
- int len = -1;
- va_start (arglist, format);
- len = vsnprintf (tmp, sizeof(tmp), format, arglist);
- va_end (arglist);
- if (len > sizeof(tmp)-1)
-return false;
- push_option (o, string_alloc (tmp, &o->gc), msglevel);
- return true;
-}
-
void
push_reset (struct options *o)
{
@@ -580,8 +542,7 @@ process_incoming_push_request (struct context *c)
}
else
{
- if (prepare_push_reply(&c->options, c->c2.tls_multi) &&
- send_push_reply (c))
+ if (send_push_reply (c))
{
ret = PUSH_MSG_REQUEST;
c->c2.sent_push_reply_expiry = now + 30;
--
1.9.1