VtConn* vtconn(int infd, int outfd) { VtConn *z; NetConnInfo *nci; z = vtmallocz(sizeof(VtConn)); z->tagrend.l = &z->lk; z->rpcfork.l = &z->lk; z->infd = infd; z->outfd = outfd; z->part = packetalloc(); nci = getnetconninfo(nil, infd); if(nci == nil) snprint(z->addr, sizeof z->addr, "/dev/fd/%d", infd); else{ strecpy(z->addr, z->addr+sizeof z->addr, nci->raddr); freenetconninfo(nci); } return z; }
void main(int argc, char **argv) { char *netdir; char buf[1024]; netdir = nil; quotefmtinstall(); fmtinstall('I', eipfmt); starttime = time(0); ARGBEGIN{ case 'a': authenticate = 1; break; case 'c': tlscert = EARGF(usage()); break; case 'D': Dflag++; break; case 'd': debug++; break; case 'f': /* disallow relaying */ fflag = 1; break; case 'g': gflag = 1; break; case 'h': /* default domain name */ dom = EARGF(usage()); break; case 'k': /* prohibited ip address */ addbadguy(EARGF(usage())); break; case 'm': /* set mail command */ mailer = mailerpath(EARGF(usage())); break; case 'n': /* log peer ip address */ netdir = EARGF(usage()); break; case 'p': passwordinclear = 1; break; case 'r': rflag = 1; /* verify sender's domain */ break; case 's': /* save blocked messages */ sflag = 1; break; case 't': fprint(2, "%s: the -t option is no longer supported, see -c\n", argv0); tlscert = "/sys/lib/ssl/smtpd-cert.pem"; break; default: usage(); }ARGEND; nci = getnetconninfo(netdir, 0); if(nci == nil) sysfatal("can't get remote system's address: %r"); parseip(rsysip, nci->rsys); if(mailer == nil) mailer = mailerpath("send"); if(debug){ snprint(buf, sizeof buf, "%s/smtpdb/%ld", UPASLOG, time(0)); close(2); if (create(buf, OWRITE | OEXCL, 0662) >= 0) { seek(2, 0, 2); fprint(2, "%d smtpd %s\n", getpid(), thedate()); } else debug = 0; } getconf(); if (isbadguy()) exits("banned"); Binit(&bin, 0, OREAD); if (chdir(UPASLOG) < 0) syslog(0, "smtpd", "no %s: %r", UPASLOG); me = sysname_read(); if(dom == 0 || dom[0] == 0) dom = domainname_read(); if(dom == 0 || dom[0] == 0) dom = me; parseinit(); sayhi(); /* allow 45 minutes to parse the header */ atnotify(catchalarm, 1); alarm(45*60*1000); zzparse(); exits(0); }
void main(int argc, char *argv[]) { uchar buf[8*1024], *p; char addr[128], dir[40], ldir[40], *s; int cmd, fd, cfd, n; NetConnInfo *nc; fmtinstall('I', eipfmt); setnetmtpt(inside, sizeof(inside), 0); setnetmtpt(outside, sizeof(outside), 0); ARGBEGIN { case 'x': setnetmtpt(inside, sizeof(inside), ARGF()); break; case 'o': setnetmtpt(outside, sizeof(outside), ARGF()); break; } ARGEND; /* ver+cmd or ver+nmethod */ if(readn(0, buf, 2) != 2) return; socksver = buf[0]; if(socksver < 4) return; if(socksver > 5) socksver = 5; if(socksver == 4){ /* port+ip4 */ if(readn(0, buf+2, 2+4) != 2+4) return; /* +user\0 */ for(p = buf+2+2+4;; p++){ if(p >= buf+sizeof(buf)) return; if(read(0, p, 1) != 1) return; if(*p == 0) break; } /* socks 4a dom hack */ if((buf[4] | buf[5] | buf[6]) == 0 && buf[7]){ /* +dom\0 */ for(++p;; p++){ if(p >= buf+sizeof(buf)) return; if(read(0, p, 1) != 1) return; if(*p == 0) break; } } } else { /* nmethod */ if((n = buf[1]) > 0) if(readn(0, buf+2, n) != n) return; /* ver+method */ buf[0] = socksver; buf[1] = 0x00; /* no authentication required */ if(write(1, buf, 2) != 2) return; /* ver+cmd+res+atyp */ if(readn(0, buf, 4) != 4) return; switch(buf[3]){ default: return; case 0x01: /* +ipv4 */ if(readn(0, buf+4, 4+2) != 4+2) return; break; case 0x03: /* +len+dom[len] */ if(readn(0, buf+4, 1) != 1) return; if((n = buf[4]) == 0) return; if(readn(0, buf+5, n+2) != n+2) return; break; case 0x04: /* +ipv6 */ if(readn(0, buf+4, 16+2) != 16+2) return; break; } } dir[0] = 0; fd = cfd = -1; cmd = buf[1]; switch(cmd){ case 0x01: /* CONNECT */ snprint(addr, sizeof(addr), "%s/tcp", outside); if((s = addr2str(addr, buf)) == nil) break; alarm(30000); fd = dial(s, 0, dir, &cfd); alarm(0); break; case 0x02: /* BIND */ if(myipaddr(buf, outside) < 0) break; snprint(addr, sizeof(addr), "%s/tcp!%I!0", outside, buf); fd = announce(addr, dir); break; case 0x03: /* UDP */ if(myipaddr(buf, inside) < 0) break; snprint(addr, sizeof(addr), "%s/udp!%I!0", inside, buf); fd = announce(addr, dir); break; } Reply: /* reply */ buf[1] = sockerr(fd < 0); /* status */ if(socksver == 4){ buf[0] = 0x00; /* vc */ if(fd < 0){ memset(buf+2, 0, 2+4); write(1, buf, 2+2+4); return; } } else { buf[0] = socksver; /* ver */ buf[2] = 0x00; /* res */ if(fd < 0){ buf[3] = 0x01; /* atyp */ memset(buf+4, 0, 4+2); write(1, buf, 4+4+2); return; } } if((nc = getnetconninfo(dir, cfd)) == nil) return; if((n = str2addr((cmd & 0x100) ? nc->raddr : nc->laddr, buf)) <= 0) return; if(write(1, buf, n) != n) return; switch(cmd){ default: return; case 0x01: /* CONNECT */ break; case 0x02: /* BIND */ cfd = listen(dir, ldir); close(fd); fd = -1; if(cfd >= 0){ strcpy(dir, ldir); fd = accept(cfd, dir); } cmd |= 0x100; goto Reply; case 0x102: break; case 0x03: /* UDP */ if(udprelay(fd, dir) == 0) while(read(0, buf, sizeof(buf)) > 0) ; goto Hangup; } /* relay data */ switch(rfork(RFMEM|RFPROC|RFFDG|RFNOWAIT)){ case -1: return; case 0: dup(fd, 0); break; default: dup(fd, 1); } while((n = read(0, buf, sizeof(buf))) > 0) if(write(1, buf, n) != n) break; Hangup: if(cfd >= 0) hangup(cfd); postnote(PNGROUP, getpid(), "kill"); }