packages: igmpproxy: prevent leakage of e.g. UPnP servers to upstream
authorJonas Gorski <jogo@openwrt.org>
Tue, 17 Apr 2012 11:47:52 +0000 (11:47 +0000)
committerJonas Gorski <jogo@openwrt.org>
Tue, 17 Apr 2012 11:47:52 +0000 (11:47 +0000)
SVN-Revision: 31331

net/igmpproxy/Makefile
net/igmpproxy/patches/003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch [new file with mode: 0644]
net/igmpproxy/patches/004-Restrict-igmp-reports-forwarding-to-upstream-interfa.patch [new file with mode: 0644]

index ebf3a56f1b64e33a7712aafc0411f7a84ae8f723..acc00b819a646e87483fa9d2e37f220f6106266c 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=igmpproxy
 PKG_VERSION:=0.1
 
 PKG_NAME:=igmpproxy
 PKG_VERSION:=0.1
-PKG_RELEASE:=5
+PKG_RELEASE:=6
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=@SF/igmpproxy
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=@SF/igmpproxy
diff --git a/net/igmpproxy/patches/003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch b/net/igmpproxy/patches/003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch
new file mode 100644 (file)
index 0000000..90d4d5f
--- /dev/null
@@ -0,0 +1,164 @@
+From 65f777e7f66b55239d935c1cf81bb5abc0f6c89f Mon Sep 17 00:00:00 2001
+From: Grinch <grinch79@users.sourceforge.net>
+Date: Sun, 16 Aug 2009 19:58:26 +0500
+Subject: [PATCH] Restrict igmp reports for downstream interfaces (wrt #2833339)
+
+atm all igmp membership reports are forwarded to the upstream interface.
+Unfortunately some ISP Providers restrict some multicast groups (esp. those
+that are defined as local link groups and that are not supposed to be
+forwarded to the wan, i.e 224.0.0.0/24). Therefore there should be some
+kind of black oder whitelisting.
+As whitelisting can be accomplished quite easy I wrote a litte patch, which
+is attached to this request.
+---
+ doc/igmpproxy.conf.5.in |   19 +++++++++++++++++++
+ src/config.c            |   23 ++++++++++++++++++++++-
+ src/igmpproxy.h         |    1 +
+ src/request.c           |   20 ++++++++++++++++----
+ 4 files changed, 58 insertions(+), 5 deletions(-)
+
+diff --git a/doc/igmpproxy.conf.5.in b/doc/igmpproxy.conf.5.in
+index a4ea7d0..56efa22 100644
+--- a/doc/igmpproxy.conf.5.in
++++ b/doc/igmpproxy.conf.5.in
+@@ -116,6 +116,25 @@ This is especially useful for the upstream interface, since the source for multi
+ traffic is often from a remote location. Any number of altnet parameters can be specified.
+ .RE
++.B whitelist
++.I networkaddr
++.RS
++Defines a whitelist for multicast groups. The network address must be in the following
++format 'a.b.c.d/n'. If you want to allow one single group use a network mask of /32,
++i.e. 'a.b.c.d/32'. 
++
++By default all multicast groups are allowed on any downstream interface. If at least one
++whitelist entry is defined, all igmp membership reports for not explicitly whitelisted
++multicast groups will be ignored and therefore not be served by igmpproxy. This is especially
++useful, if your provider does only allow a predefined set of multicast groups. These whitelists
++are only obeyed by igmpproxy itself, they won't prevent any other igmp client running on the
++same machine as igmpproxy from requesting 'unallowed' multicast groups.
++
++You may specify as many whitelist entries as needed. Although you should keep it as simple as
++possible, as this list is parsed for every membership report and therefore this increases igmp
++response times. Often used or large groups should be defined first, as parsing ends as soon as
++a group matches an entry.
++.RE
+ .SH EXAMPLE
+ ## Enable quickleave
+diff --git a/src/config.c b/src/config.c
+index 5a96ce0..d72619f 100644
+--- a/src/config.c
++++ b/src/config.c
+@@ -46,6 +46,9 @@ struct vifconfig {
+     // Keep allowed nets for VIF.
+     struct SubnetList*  allowednets;
++
++    // Allowed Groups
++    struct SubnetList*  allowedgroups;
+     
+     // Next config in list...
+     struct vifconfig*   next;
+@@ -202,6 +205,8 @@ void configureVifs() {
+                     // Insert the configured nets...
+                     vifLast->next = confPtr->allowednets;
++                  Dp->allowedgroups = confPtr->allowedgroups;
++
+                     break;
+                 }
+             }
+@@ -215,7 +220,7 @@ void configureVifs() {
+ */
+ struct vifconfig *parsePhyintToken() {
+     struct vifconfig  *tmpPtr;
+-    struct SubnetList **anetPtr;
++    struct SubnetList **anetPtr, **agrpPtr;
+     char *token;
+     short parseError = 0;
+@@ -239,6 +244,7 @@ struct vifconfig *parsePhyintToken() {
+     tmpPtr->threshold = 1;
+     tmpPtr->state = IF_STATE_DOWNSTREAM;
+     tmpPtr->allowednets = NULL;
++    tmpPtr->allowedgroups = NULL;
+     // Make a copy of the token to store the IF name
+     tmpPtr->name = strdup( token );
+@@ -248,6 +254,7 @@ struct vifconfig *parsePhyintToken() {
+     // Set the altnet pointer to the allowednets pointer.
+     anetPtr = &tmpPtr->allowednets;
++    agrpPtr = &tmpPtr->allowedgroups; 
+     // Parse the rest of the config..
+     token = nextConfigToken();
+@@ -266,6 +273,20 @@ struct vifconfig *parsePhyintToken() {
+                 anetPtr = &(*anetPtr)->next;
+             }
+         }
++      else if(strcmp("whitelist", token)==0) {
++          // Whitelist
++          token = nextConfigToken();
++          my_log(LOG_DEBUG, 0, "Config: IF: Got whitelist token %s.", token);
++      
++          *agrpPtr = parseSubnetAddress(token);
++          if(*agrpPtr == NULL) {
++              parseError = 1;
++              my_log(LOG_WARNING, 0, "Unable to parse subnet address.");
++              break;
++          } else {
++              agrpPtr = &(*agrpPtr)->next;
++          }
++      }
+         else if(strcmp("upstream", token)==0) {
+             // Upstream
+             my_log(LOG_DEBUG, 0, "Config: IF: Got upstream token.");
+diff --git a/src/igmpproxy.h b/src/igmpproxy.h
+index 4dabd1c..0de7791 100644
+--- a/src/igmpproxy.h
++++ b/src/igmpproxy.h
+@@ -145,6 +145,7 @@ struct IfDesc {
+     short               Flags;
+     short               state;
+     struct SubnetList*  allowednets;
++    struct SubnetList*  allowedgroups;
+     unsigned int        robustness;
+     unsigned char       threshold;   /* ttl limit */
+     unsigned int        ratelimit; 
+diff --git a/src/request.c b/src/request.c
+index e3589f6..89b91de 100644
+--- a/src/request.c
++++ b/src/request.c
+@@ -82,10 +82,22 @@ void acceptGroupReport(uint32_t src, uint32_t group, uint8_t type) {
+         my_log(LOG_DEBUG, 0, "Should insert group %s (from: %s) to route table. Vif Ix : %d",
+             inetFmt(group,s1), inetFmt(src,s2), sourceVif->index);
+-        // The membership report was OK... Insert it into the route table..
+-        insertRoute(group, sourceVif->index);
+-
+-
++      // If we don't have a whitelist we insertRoute and done
++      if(sourceVif->allowedgroups == NULL)
++      {
++          insertRoute(group, sourceVif->index);
++          return;
++      }
++      // Check if this Request is legit on this interface
++      struct SubnetList *sn;
++      for(sn = sourceVif->allowedgroups; sn != NULL; sn = sn->next)
++          if((group & sn->subnet_mask) == sn->subnet_addr)
++          {
++              // The membership report was OK... Insert it into the route table..
++              insertRoute(group, sourceVif->index);
++              return;
++          }
++      my_log(LOG_INFO, 0, "The group address %s may not be requested from this interface. Ignoring.", inetFmt(group, s1));
+     } else {
+         // Log the state of the interface the report was recieved on.
+         my_log(LOG_INFO, 0, "Mebership report was recieved on %s. Ignoring.",
+-- 
+1.7.2.5
+
diff --git a/net/igmpproxy/patches/004-Restrict-igmp-reports-forwarding-to-upstream-interfa.patch b/net/igmpproxy/patches/004-Restrict-igmp-reports-forwarding-to-upstream-interfa.patch
new file mode 100644 (file)
index 0000000..a4caed7
--- /dev/null
@@ -0,0 +1,62 @@
+From bcd7c648e86d97263c931de53a008c9629e7797e Mon Sep 17 00:00:00 2001
+From: Stefan Becker <stefan.becker@nokia.com>
+Date: Fri, 11 Dec 2009 21:08:57 +0200
+Subject: [PATCH] Restrict igmp reports forwarding to upstream interface
+
+Utilize the new "whitelist" keyword also on the upstream interface definition.
+If specified then only whitelisted multicast groups will be forwarded upstream.
+
+This can be used to avoid publishing private multicast groups to the world,
+e.g. SSDP from a UPnP server on the internal network.
+---
+ doc/igmpproxy.conf.5.in |    5 +++++
+ src/rttable.c           |   17 +++++++++++++++++
+ 2 files changed, 22 insertions(+), 0 deletions(-)
+
+diff --git a/doc/igmpproxy.conf.5.in b/doc/igmpproxy.conf.5.in
+index 56efa22..d916f05 100644
+--- a/doc/igmpproxy.conf.5.in
++++ b/doc/igmpproxy.conf.5.in
+@@ -134,6 +134,11 @@ You may specify as many whitelist entries as needed. Although you should keep it
+ possible, as this list is parsed for every membership report and therefore this increases igmp
+ response times. Often used or large groups should be defined first, as parsing ends as soon as
+ a group matches an entry.
++
++You may also specify whitelist entries for the upstream interface. Only igmp membership reports
++for explicitely whitelisted multicast groups will be sent out on the upstream interface. This
++is useful if you want to use multicast groups only between your downstream interfaces, like SSDP
++from a UPnP server.
+ .RE
+ .SH EXAMPLE
+diff --git a/src/rttable.c b/src/rttable.c
+index f0701a8..77dd791 100644
+--- a/src/rttable.c
++++ b/src/rttable.c
+@@ -117,6 +117,23 @@ void sendJoinLeaveUpstream(struct RouteTable* route, int join) {
+         my_log(LOG_ERR, 0 ,"FATAL: Unable to get Upstream IF.");
+     }
++    // Check if there is a white list for the upstram VIF
++    if (upstrIf->allowedgroups != NULL) {
++      uint32_t           group = route->group;
++        struct SubnetList* sn;
++
++        // Check if this Request is legit to be forwarded to upstream
++        for(sn = upstrIf->allowedgroups; sn != NULL; sn = sn->next)
++            if((group & sn->subnet_mask) == sn->subnet_addr)
++                // Forward is OK...
++                break;
++
++        if (sn == NULL) {
++          my_log(LOG_INFO, 0, "The group address %s may not be forwarded upstream. Ignoring.", inetFmt(group, s1));
++            return;
++        }
++    }
++
+     // Send join or leave request...
+     if(join) {
+-- 
+1.7.2.5
+