Access Restrictions

Discussion in 'Tomato Firmware' started by eahm, Mar 11, 2013.

  1. eahm

    eahm LI Guru Member

    Tomato keeps surprising me...

    For example I want to block, I add the words adult or adultwebsite or adultwebsitehere or even and everything is blocked when I try to access the website. If by mistake I type everything works like there is no block.

    Are you kidding me? Tomato doesn't block capitalized letters when lowercase are blocked?
  2. Monk E. Boy

    Monk E. Boy Network Guru Member

    Well, Unix is case sensitive on virtually everything so it takes quite a bit of effort to make things case insensitive.
  3. Elfew

    Elfew Network Guru Member

    it should be enchanted...
  4. koitsu

    koitsu Network Guru Member

    I'm very familiar with the Access Restrictions "website" name limiting bits, including portions of the code that make this work:

    Jonathan Zarate (Tomato author) wrote a iptables/netfilter module called "web" which performs forms of string matching against the content portions of certain packets. Usually this gets added to the iptables rules by effectively calling this:

    iptables -A rresXX -p tcp -m web --hore \"thestringyouentered\" -j {LOGREJECT,REJECT}

    Where XX is a number (I would need to look up how the code works), thestringyouentered is the string you entered (one entry per line), and {LOGREJECT,REJECT} is either LOGREJECT or REJECT (based on if you're using logging or not) and causes a relevant ICMP message to be sent back to the client (machine on the LAN) indicating the socket was abruptly closed -- that's how the module works. If it used -j DROP the client would just sit there until a timeout was reached, which isn't ideal. I can't remember if this gets referenced in INPUT or FORWARD, but whatever.

    The --hore "mode" causes the match to happen against the entire portion of the packet and not just against the HTTP Host: header, or at least that's what the code comments claim.

    The code for "building" the iptables rules is: tomato/release/src/router/rc/restrict.c

    The code for the actual "web" iptables module is here:


    Anyway, getting down to the root cause/nitty gritty:

    ipt_web.c uses the memcmp() function, which is a raw memory comparison function, not a string-comparison function, thus always operates case-sensitive. Using string-comparison functions (specifically strncmp() or strncasecmp()) could be done, but introduces all sorts of complexities, especially considering things like IDN; a raw binary comparison solves that, but introduces other caveats, like the one you're experiencing.

    It's also very important to understand how memcmp() behaves compared to strncmp() and strncasecmp() -- it is not simply an issue of replacing the calls to accomplish what you want. Note that the string comparison functions I just listed stop their comparison once NULL ('\0') is encountered or if the provided length is reached, while memcmp() is based 100% on length.

    All this code is quite ugly/nasty, badly commented (if at all), and is hard to make heads or tails with.

    All this, and other reasons, further justifies the need for replacing this mess with the xt_string.c iptables/netfilter module (referred to as ipt_string) which is available in TomatoUSB releases (not stock Tomato), which I've discussed in the past:

    If you built your own firmware with this, then made your own iptables rules that referenced ipt_string and its syntaxes, you could accomplish case-insensitive matching (it's supported).

    *IX systems using case-sensitive filesystems is completely irrelevant WRT this matter; there are both kernel and userland functions that accomplish case-sensitive and case-insensitive string comparisons.
    eahm likes this.
  5. DJF - EasyTomato

    DJF - EasyTomato Serious Server Member

    Good info. I don't see anything in xt_string related to case-insensitive matching, do you have an example of how to specify that in an iptables rule?

    All I found was on the underlying library and using the TS_IGNORECASE flag:
  6. Monk E. Boy

    Monk E. Boy Network Guru Member

    Filesystems aside, you still have common everyday tools like grep that require a case-insensitive switch (-i) to change their default (case-sensitive) behavior, and some tools don't even have equivalent flags. Contrast this with the normal behavior under Windows, which assumes case insensitivity and you have to explicitly flag the act to be treated as case sensitive. Though neither really applies though since, as you pointed out, it's doing a memory comparison - which is case-insensitive by its very nature.

    I was actually reading up on Access Restrictions yesterday after posting my response, and read through that thread as well as others... but didn't have the time during/after to respond with a slightly more eloquent explanation. Stupid job, be less demanding on my time... the internet, she needs help...
  7. koitsu

    koitsu Network Guru Member

    What you found is correct. I have no examples, but the support for the capability is there. Happy hacking!
  8. WRD - EasyTomato

    WRD - EasyTomato Networkin' Nut Member

    Looks like xt_string can do case insensitivity with a little tweaking. We'll add this and have it out in the next EasyTomato release (sometime next week?). We'll also let Toastman and Shibby know about our commits so they can include it if they want (it also hunts for strings in DNS lookups re HTTPS blocking).
    eahm and Elfew like this.
  9. Toastman

    Toastman Super Moderator Staff Member Member

    I already added the string module as above, but not released yet. Anything that needs to be added to complete this, (work on the commands issued by the GUI) shoot it my way... :D
    Elfew and eahm like this.
  10. WRD - EasyTomato

    WRD - EasyTomato Networkin' Nut Member

    Yep! Will do.
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice