*** qmail-smtpd.c Mon Jun 15 11:53:16 1998 --- qmail-relayreject.c Sat Oct 25 15:18:40 2003 *************** *** 134,222 **** dohelo(remotehost); } - - stralloc addr = {0}; /* will be 0-terminated, if addrparse returns 1 */ - - int addrparse(arg) - char *arg; - { - int i; - char ch; - char terminator; - struct ip_address ip; - int flagesc; - int flagquoted; - - terminator = '>'; - i = str_chr(arg,'<'); - if (arg[i]) - arg += i + 1; - else { /* partner should go read rfc 821 */ - terminator = ' '; - arg += str_chr(arg,':'); - if (*arg == ':') ++arg; - while (*arg == ' ') ++arg; - } - - /* strip source route */ - if (*arg == '@') while (*arg) if (*arg++ == ':') break; - - if (!stralloc_copys(&addr,"")) die_nomem(); - flagesc = 0; - flagquoted = 0; - for (i = 0;ch = arg[i];++i) { /* copy arg to addr, stripping quotes */ - if (flagesc) { - if (!stralloc_append(&addr,&ch)) die_nomem(); - flagesc = 0; - } - else { - if (!flagquoted && (ch == terminator)) break; - switch(ch) { - case '\\': flagesc = 1; break; - case '"': flagquoted = !flagquoted; break; - default: if (!stralloc_append(&addr,&ch)) die_nomem(); - } - } - } - /* could check for termination failure here, but why bother? */ - if (!stralloc_append(&addr,"")) die_nomem(); - - if (liphostok) { - i = byte_rchr(addr.s,addr.len,'@'); - if (i < addr.len) /* if not, partner should go read rfc 821 */ - if (addr.s[i + 1] == '[') - if (!addr.s[i + 1 + ip_scanbracket(addr.s + i + 1,&ip)]) - if (ipme_is(&ip)) { - addr.len = i + 1; - if (!stralloc_cat(&addr,&liphost)) die_nomem(); - if (!stralloc_0(&addr)) die_nomem(); - } - } - - if (addr.len > 900) return 0; - return 1; - } - - int bmfcheck() - { - int j; - if (!bmfok) return 0; - if (constmap(&mapbmf,addr.s,addr.len - 1)) return 1; - j = byte_rchr(addr.s,addr.len,'@'); - if (j < addr.len) - if (constmap(&mapbmf,addr.s + j,addr.len - j - 1)) return 1; - return 0; - } - - int addrallowed() - { - int r; - r = rcpthosts(addr.s,str_len(addr.s)); - if (r == -1) die_control(); - return r; - } - - int seenmail = 0; int flagbarf; /* defined if seenmail */ stralloc mailfrom = {0}; --- 134,139 ---- *************** *** 237,269 **** seenmail = 0; out("250 flushed\r\n"); } ! void smtp_mail(arg) char *arg; { ! if (!addrparse(arg)) { err_syntax(); return; } ! flagbarf = bmfcheck(); ! seenmail = 1; ! if (!stralloc_copys(&rcptto,"")) die_nomem(); ! if (!stralloc_copys(&mailfrom,addr.s)) die_nomem(); ! if (!stralloc_0(&mailfrom)) die_nomem(); ! out("250 ok\r\n"); } - void smtp_rcpt(arg) char *arg; { - if (!seenmail) { err_wantmail(); return; } - if (!addrparse(arg)) { err_syntax(); return; } - if (flagbarf) { err_bmf(); return; } - if (relayclient) { - --addr.len; - if (!stralloc_cats(&addr,relayclient)) die_nomem(); - if (!stralloc_0(&addr)) die_nomem(); - } - else - if (!addrallowed()) { err_nogateway(); return; } - if (!stralloc_cats(&rcptto,"T")) die_nomem(); - if (!stralloc_cats(&rcptto,addr.s)) die_nomem(); - if (!stralloc_0(&rcptto)) die_nomem(); - out("250 ok\r\n"); - } - int saferead(fd,buf,len) int fd; char *buf; int len; { --- 154,164 ---- seenmail = 0; out("250 flushed\r\n"); } ! ! void smtp_relayreject(arg) char *arg; { ! out("553 sorry, no mail accepted from an open relay; check your server configs (#5.7.1)\r\n"); } int saferead(fd,buf,len) int fd; char *buf; int len; { *************** *** 290,403 **** qmail_put(&qqt,ch,1); } - void blast(hops) - int *hops; - { - char ch; - int state; - int flaginheader; - int pos; /* number of bytes since most recent \n, if fih */ - int flagmaybex; /* 1 if this line might match RECEIVED, if fih */ - int flagmaybey; /* 1 if this line might match \r\n, if fih */ - int flagmaybez; /* 1 if this line might match DELIVERED, if fih */ - - state = 1; - *hops = 0; - flaginheader = 1; - pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; - for (;;) { - substdio_get(&ssin,&ch,1); - if (flaginheader) { - if (pos < 9) { - if (ch != "delivered"[pos]) if (ch != "DELIVERED"[pos]) flagmaybez = 0; - if (flagmaybez) if (pos == 8) ++*hops; - if (pos < 8) - if (ch != "received"[pos]) if (ch != "RECEIVED"[pos]) flagmaybex = 0; - if (flagmaybex) if (pos == 7) ++*hops; - if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0; - if (flagmaybey) if (pos == 1) flaginheader = 0; - } - ++pos; - if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; } - } - switch(state) { - case 0: - if (ch == '\n') straynewline(); - if (ch == '\r') { state = 4; continue; } - break; - case 1: /* \r\n */ - if (ch == '\n') straynewline(); - if (ch == '.') { state = 2; continue; } - if (ch == '\r') { state = 4; continue; } - state = 0; - break; - case 2: /* \r\n + . */ - if (ch == '\n') straynewline(); - if (ch == '\r') { state = 3; continue; } - state = 0; - break; - case 3: /* \r\n + .\r */ - if (ch == '\n') return; - put("."); - put("\r"); - if (ch == '\r') { state = 4; continue; } - state = 0; - break; - case 4: /* + \r */ - if (ch == '\n') { state = 1; break; } - if (ch != '\r') { put("\r"); state = 0; } - } - put(&ch); - } - } - - char accept_buf[FMT_ULONG]; - void acceptmessage(qp) unsigned long qp; - { - datetime_sec when; - when = now(); - out("250 ok "); - accept_buf[fmt_ulong(accept_buf,(unsigned long) when)] = 0; - out(accept_buf); - out(" qp "); - accept_buf[fmt_ulong(accept_buf,qp)] = 0; - out(accept_buf); - out("\r\n"); - } - - void smtp_data() { - int hops; - unsigned long qp; - char *qqx; - - if (!seenmail) { err_wantmail(); return; } - if (!rcptto.len) { err_wantrcpt(); return; } - seenmail = 0; - if (databytes) bytestooverflow = databytes + 1; - if (qmail_open(&qqt) == -1) { err_qqt(); return; } - qp = qmail_qp(&qqt); - out("354 go ahead\r\n"); - - received(&qqt,"SMTP",local,remoteip,remotehost,remoteinfo,fakehelo); - blast(&hops); - hops = (hops >= MAXHOPS); - if (hops) qmail_fail(&qqt); - qmail_from(&qqt,mailfrom.s); - qmail_put(&qqt,rcptto.s,rcptto.len); - - qqx = qmail_close(&qqt); - if (!*qqx) { acceptmessage(qp); return; } - if (hops) { out("554 too many hops, this message is looping (#5.4.6)\r\n"); return; } - if (databytes) if (!bytestooverflow) { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); return; } - if (*qqx == 'D') out("554 "); else out("451 "); - out(qqx + 1); - out("\r\n"); - } - struct commands smtpcommands[] = { ! { "rcpt", smtp_rcpt, 0 } ! , { "mail", smtp_mail, 0 } ! , { "data", smtp_data, flush } , { "quit", smtp_quit, flush } , { "helo", smtp_helo, flush } , { "ehlo", smtp_ehlo, flush } --- 185,194 ---- qmail_put(&qqt,ch,1); } struct commands smtpcommands[] = { ! { "rcpt", smtp_relayreject, 0 } ! , { "mail", smtp_relayreject, 0 } ! , { "data", smtp_relayreject, 0 } , { "quit", smtp_quit, flush } , { "helo", smtp_helo, flush } , { "ehlo", smtp_ehlo, flush }