[nycbug-talk] some C help?

Marc Spitzer mspitzer at gmail.com
Sat Mar 10 02:41:53 EST 2007


Well I could let a real programmer handle this, but how would that be
fun?  see below

On 3/10/07, Charles Sprickman <spork at bway.net> wrote:
> Hi All,
>
> I'm playing around with a FreeBSD port of spamd/spamlogd from OpenBSD that
> someone posted here some time ago.
>
> Spamd seems to work, spamlogd seems to almost work.  It's C, so I'm a
> little lost, but I am able to find the area where things are getting
> screwed up.  In short, spamlogd runs tcpdump with some very specific flags
> to look for inbound or outbound mail, finds an IP in the tcpdump output,
> and then throws it into the spamd db as whitelisted.  For example, in my
> case I'm looking at outbound mail - generally mxers that *I* send to are
> not going to be spamming me - they are more likely going to be legit
> servers.
>
> So I have a pf rule to tag the traffic, and spamlogd is catching it, but
> some pattern matching must be going awry.  Here I'm sending mail to a host
> at 10.10.10.10, and this is what tcpdump sees (called with the same args
> spamlogd is using):
>
> listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 68
> bytes
> rule 12/0(match): pass out on fxp0: 10.10.10.9 > 10.10.10.10: [|tcp]
>
> But then it spits this out to syslog:
>
> Mar 10 00:09:24 slimjim spamlogd[72636]: invalid ip address 10.10.10
>
> Note the lack of the final octet.
>
> This is (I hope) the area where spamlogd parses the output of tcpdump:
>
>             if (strstr(buf, "pass out") != NULL) {
>                     /*
>                      * this is outbound traffic - we whitelist
>                      * the destination address, because we assume
>                      * that a reply may come to this outgoing mail
>                      * we are sending.
>                      */
>                  if (!inbound && (cp = (strchr(buf, '>'))) != NULL) {
>                          if (sscanf(cp, "> %s", buf2) == 1) {
>                                  cp = strrchr(buf2, '.');

strrchr looks for the last ocurance of '.' in buf2, good chance it is
the '.' before the last octect

>                                  if (cp != NULL) {
>                                          *cp = '\0';
this sets the char cp points to to null, terminating the string at that point.

>                                          cp = buf2;
this sets cp to the beggining of buf2 above
>                                          syslog_r(LOG_DEBUG, &sdata,
>                                              "outbound %s\n", cp);
>                                   }
>                            } else
>                                 cp = NULL;
>                            }
>
>                 } else {
>                    /* next is the inbound check...  */
>
> That chunk makes very little sense to me.

starting where buf2 shows up, lets say buf2 looks like this:
"1.2.3.4"
after the cp='\0' bit it looks like this:
"1.2.3'\0'4"

and syslog stops at the '\0' that seperates 3 and 4, null terminated
string and all.



>
> Can anyone give me a quick shove in the right direction?

If you follow my advice you are doomed.

marc
-- 
Freedom is nothing but a chance to be better.
Albert Camus



More information about the talk mailing list