Skip to contentSkip to conversation

This patch implements the command kill addr:port for mixed ipv4 and ipv6.

PATCH New Stephan Kunz 1 participant 1 message Mar 14, 2017

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 This patch implements the command kill addr:port for mixed ipv4 and ipv6.

The old command was only working for ipv4 and we needed the possibility to also kill other addresses. I did throw away the old parsing by ':' and now search for the last occurrence of a colon. If a colon is found the part after the colon is parsed and checked if it is a valid port. If this is the case I check via pton if the address is v4 or v6 and fill the openvpn_sockaddr accordingly. If not I assume we have a cn.

The patch supports following kill-commands:
kill ipv6:port, kill ::ffff:ipv4:port, kill ipv4:port, kill cn

---
 src/openvpn/buffer.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/buffer.h | 27 +++++++++++++++
 src/openvpn/manage.c | 89 ++++++++++++++++++++++++++++++-------------------
 src/openvpn/manage.h |  2 +-
 src/openvpn/multi.c  | 18 ++++------
 5 files changed, 183 insertions(+), 47 deletions(-)
src/openvpn/buffer.c +94 -0
index 2defd18..1c0ac81 100644
@@ -828,6 +828,100 @@ buf_parse(struct buffer *buf, const int delim, char *line, const int size)
 }
 
 /*
+ * parses string for the last occurance of a given delim
+ */
+int
+find_last_occurence_of_delim(struct buffer *buf, const int delim)
+{
+    bool found = false;
+
+    int idx = buf->len;
+    int delim_index = 0;
+
+    while (idx > 0 && !found)
+    {
+        delim_index = buf_read_u8_at_idx(buf, --idx);
+        if (delim_index == delim)
+        {
+            found = true;
+        }
+    }
+
+    if (!found)
+    {
+        return -1;
+    }
+
+    return idx;
+}
+
+/*
+ * String parsing from a given index to the eol
+ */
+bool
+buf_parse_from_idx(struct buffer *buf, const int start_idx, char *line, const int size)
+{
+    bool eol = false;
+
+    int idx = start_idx;
+    int n = 0;
+    int c;
+
+    ASSERT (size > 0);
+
+    do
+    {
+        c = buf_read_u8_at_idx(buf, idx++);
+        if (c < 0)
+        {
+            eol = true;
+            c = 0;
+        }
+        if (n >= size)
+        {
+            break;
+        }
+        line[n++] = c;
+    }
+    while (c);
+
+    line[size-1] = '\0';
+    return !(eol && !strlen (line));
+}
+
+/*
+ * String parsing from beginning to given index
+ */
+bool
+buf_parse_to_idx(struct buffer *buf, const int stop_idx, char *line, const int size)
+{
+    bool eol = false;
+    int n = 0;
+    int c;
+
+    ASSERT (size > 0);
+
+    do
+    {
+        c = buf_read_u8(buf);
+        if (c < 0)
+        {
+            eol = true;
+            c = 0;
+        }
+        if (n >= size)
+        {
+            break;
+        }
+        line[n++] = c;
+    }
+    while (c && buf->offset < stop_idx);
+
+    line[buf->offset] = '\0';
+    return !(eol && !strlen (line));
+}
+
+/*
  * Print a string which might be NULL
  */
 const char *
src/openvpn/buffer.h +27 -0
index 28b224e..851e923 100644
@@ -486,6 +486,21 @@ void convert_to_one_line(struct buffer *buf);
 bool buf_parse(struct buffer *buf, const int delim, char *line, const int size);
 
 /*
+ * Parse a string from end to beginning based on a given delimiter char
+ */
+bool buf_parse_from_idx (struct buffer *buf, const int start_idx, char *line, const int size);
+
+/*
+ * String parsing from beginning to given index
+ */
+bool buf_parse_to_idx (struct buffer *buf, const int stop_idx, char *line, const int size);
+
+/*
+ * looks for the last occurence of a given delimiter char
+ */
+int find_last_occurence_of_delim (struct buffer *buf, const int delim);
+
+/*
  * Hex dump -- Output a binary buffer to a hex string and return it.
  */
 #define FHE_SPACE_BREAK_MASK 0xFF /* space_break parameter in lower 8 bits */
@@ -782,6 +797,18 @@ buf_read(struct buffer *src, void *dest, int size)
 }
 
 static inline int
+buf_read_u8_at_idx(struct buffer *buf, int idx)
+{
+    int ret;
+    if (BLEN (buf) < 1 || BLEN (buf) < idx)
+    {
+        return -1;
+    }
+    ret = *(buf->data+idx);
+    return ret;
+}
+
+static inline int
 buf_read_u8(struct buffer *buf)
 {
     int ret;
src/openvpn/manage.c +54 -35

114 lines not on this page · raw message

src/openvpn/manage.h +1 -1
index 6e5cb9b..e143e2d 100644
@@ -162,7 +162,7 @@ struct management_callback
     void (*status) (void *arg, const int version, struct status_output *so);
     void (*show_net) (void *arg, const int msglevel);
     int (*kill_by_cn) (void *arg, const char *common_name);
-    int (*kill_by_addr) (void *arg, const in_addr_t addr, const int port);
+    int (*kill_by_addr) (void *arg, struct openvpn_sockaddr *saddr);
     void (*delete_event) (void *arg, event_t event);
     int (*n_clients) (void *arg);
 #ifdef MANAGEMENT_DEF_AUTH
src/openvpn/multi.c +7 -11
index f6f3f5d..93f0f6c 100644
@@ -3157,23 +3157,18 @@ management_callback_kill_by_cn(void *arg, const char *del_cn)
 }
 
 static int
-management_callback_kill_by_addr(void *arg, const in_addr_t addr, const int port)
+management_callback_kill_by_addr(void *arg, struct openvpn_sockaddr *saddr)
 {
     struct multi_context *m = (struct multi_context *) arg;
     struct hash_iterator hi;
     struct hash_element *he;
-    struct openvpn_sockaddr saddr;
     struct mroute_addr maddr;
     int count = 0;
 
-    CLEAR(saddr);
-    saddr.addr.in4.sin_family = AF_INET;
-    saddr.addr.in4.sin_addr.s_addr = htonl(addr);
-    saddr.addr.in4.sin_port = htons(port);
-    if (mroute_extract_openvpn_sockaddr(&maddr, &saddr, true))
+    if (mroute_extract_openvpn_sockaddr(&maddr, saddr, true))
     {
-        hash_iterator_init(m->iter, &hi);
-        while ((he = hash_iterator_next(&hi)))
+        hash_iterator_init (m->iter, &hi);
+        while ((he = hash_iterator_next (&hi)))
         {
             struct multi_instance *mi = (struct multi_instance *) he->value;
             if (!mi->halt && mroute_addr_equal(&maddr, &mi->real))
@@ -3182,8 +3177,9 @@ management_callback_kill_by_addr(void *arg, const in_addr_t addr, const int port
                 ++count;
             }
         }
-        hash_iterator_free(&hi);
-    }
+        hash_iterator_free (&hi);
+   }
+
     return count;
 }
 
Signature · 1 line
1.8.2.3