*** tcpserver.c.orig Wed Mar 14 10:21:33 2001 --- tcpserver.c Fri Mar 16 13:53:52 2001 *************** *** 1,3 **** --- 1,4 ---- + #include #include #include #include *************** *** 25,36 **** --- 26,39 ---- #include "ndelay.h" #include "remoteinfo.h" #include "rules.h" + #include "db.h" #include "sig.h" #include "dns.h" int verbosity = 1; int flagkillopts = 1; int flagdelay = 1; + int usemysql = 0; char *banner = ""; int flagremoteinfo = 1; int flagremotehost = 1; *************** *** 109,114 **** --- 112,121 ---- { strerr_die4sys(111,DROP,"unable to read ",fnrules,": "); } + void drop_db(void) + { + strerr_die4sys(111,DROP,"unable to verify DB ",db_database,": "); + } void found(char *data,unsigned int datalen) { *************** *** 198,205 **** } env("TCPREMOTEINFO",flagremoteinfo ? tcpremoteinfo.s : 0); ! if (fnrules) { int fdrules; fdrules = open_read(fnrules); if (fdrules == -1) { if (errno != error_noent) drop_rules(); --- 205,222 ---- } env("TCPREMOTEINFO",flagremoteinfo ? tcpremoteinfo.s : 0); ! if(usemysql) { ! if(flagdeny==2) { ! /* drop_db(); */ ! } else if(!flagdeny) { ! env("RELAYCLIENT",""); ! } ! flagdeny=0; ! } ! ! if(fnrules) { int fdrules; + fdrules = open_read(fnrules); if (fdrules == -1) { if (errno != error_noent) drop_rules(); *************** *** 240,246 **** { strerr_warn1("\ tcpserver: usage: tcpserver \ ! [ -1UXpPhHrRoOdDqQv ] \ [ -c limit ] \ [ -x rules.cdb ] \ [ -B banner ] \ --- 257,263 ---- { strerr_warn1("\ tcpserver: usage: tcpserver \ ! [ -1UXpPhHrRoOdDqQvS ] \ [ -c limit ] \ [ -x rules.cdb ] \ [ -B banner ] \ *************** *** 300,306 **** int s; int t; ! while ((opt = getopt(argc,argv,"dDvqQhHrR1UXx:t:u:g:l:b:B:c:pPoO")) != opteof) switch(opt) { case 'b': scan_ulong(optarg,&backlog); break; case 'c': scan_ulong(optarg,&limit); break; --- 317,323 ---- int s; int t; ! while ((opt = getopt(argc,argv,"dDvqQhHrR1UXSx:t:u:g:l:b:B:c:pPoO")) != opteof) switch(opt) { case 'b': scan_ulong(optarg,&backlog); break; case 'c': scan_ulong(optarg,&limit); break; *************** *** 327,332 **** --- 344,350 ---- case 'g': scan_ulong(optarg,&gid); break; case '1': flag1 = 1; break; case 'l': localhost = optarg; break; + case 'S': usemysql = 1; break; default: usage(); } argc -= optind; *************** *** 398,403 **** --- 416,422 ---- for (;;) { while (numchildren >= limit) sig_pause(); + flagdeny=0; sig_unblock(sig_child); t = socket_accept4(s,remoteip,&remoteport); sig_block(sig_child); *************** *** 405,410 **** --- 424,499 ---- if (t == -1) continue; ++numchildren; printstatus(); + if(usemysql) { + int ret; + + remoteipstr[ip4_fmt(remoteipstr,remoteip)] = 0; + + if(db_port==-1) { + FILE *fp; + + if(fp=fopen("/var/qmail/control/sql","r")) { + char line[256]; + char tag[256]; + char value[256]; + + while(fgets(line,256,fp)) { + char *comment; + + if(comment=strchr(line,'#')) { + *comment='\0'; + } + if(sscanf(line,"%s\t%s\n", tag, value) != 2) continue; + /* fprintf(stderr,"Warning: got Line: [%s]\n",line); */ + + /* + server sql.domain.com + port 3306 + database vpopmail + table relay + user vpopmail + pass secret + time 1800 + */ + if(!strcasecmp(tag,"server")) { + strcpy(db_host,value); + } else if(!strcasecmp(tag,"port")) { + db_port = atoi(value); + } else if(!strcasecmp(tag,"database")) { + strcpy(db_database,value); + } else if(!strcasecmp(tag,"table")) { + strcpy(db_table,value); + } else if(!strcasecmp(tag,"user")) { + strcpy(db_user,value); + } else if(!strcasecmp(tag,"pass")) { + strcpy(db_password,value); + } else if(!strcasecmp(tag,"time")) { + pop_timeout=atoi(value); + } else { + fprintf(stderr,"Warning: Bad sql: TAG: [%s] VALUE: [%s]\n",tag,value); + } + } + } + if(db_port==-1) { + fprintf(stderr,"Error: Failed to read /var/qmail/control/sql\n"); + db_port==-2; + } else { + fclose(fp); + } + if (verbosity >= 2) { + fprintf(stderr,"db_port set to: [%d]\n", db_port); + } + } + if(db_port>=0) { + db_ping(); + if((ret=check_db(remoteipstr))==-1) { + flagdeny=2; + } else if(ret) { + flagdeny=1; + } + } + } + switch(fork()) { case 0: close(s); *** db.c.orig Fri Mar 16 13:20:22 2001 --- db.c Wed Mar 14 15:13:05 2001 *************** *** 0 **** --- 1,122 ---- + #include + #include + #include + #include + #include "db.h" + + /* + server sql.mailserver.com + port 3306 + database vpopmail + table relay + user vpopmail + pass secret + time 1800 + */ + #define MAX_QUERY_STRING 160 + + MYSQL *dbh=NULL; + + char db_database[256]; + char db_host[256]; + char db_table[256]; + char db_user[256]; + char db_password[256]; + int db_port=-1; + int pop_timeout; + + extern int verbosity; + + int open_db(char *database, char *host, int port, char *username, char *password) + { + MYSQL *tmp; + + if (dbh != NULL) { + mysql_close(dbh); + dbh = NULL; + } + dbh = (MYSQL *)mysql_init(NULL); + if (dbh == NULL) + { + fprintf(stderr,"MYSQL Init Error:\n"); + return -1; + } + + tmp = mysql_real_connect(dbh, host, username, password, database, port, NULL,0); + + if (!tmp) + { + fprintf(stderr,"MYSQL Error: %s\n",mysql_error(dbh)); + return -1; + } + + return 0; + } + + int check_db(char *remoteip) { + char query[MAX_QUERY_STRING]; + int num_rows = 0; + int ret = -1; + MYSQL_RES *res; + + snprintf(query,MAX_QUERY_STRING,"SELECT timestamp FROM %s WHERE '%s' LIKE CONCAT(ip_addr,'%%') AND (timestamp>(UNIX_TIMESTAMP()-%d) OR timestamp IS NULL )", db_table, remoteip, pop_timeout); + + ret = mysql_query(dbh,query); + res = mysql_store_result(dbh); + num_rows = mysql_affected_rows(dbh); + mysql_free_result(res); + + if (ret) { + char err_str[256]; + + snprintf(err_str,255,"-%s-",mysql_error(dbh)); + fprintf(stderr,"%s",err_str); + if(strstr("server has gone away",err_str)) { + db_close(); + db_ping(); + + ret = mysql_query(dbh,query); + if (ret) { + return -1; + } + } else { + db_close(); + db_ping(); + + ret = mysql_query(dbh,query); + if (ret) { + return -1; + } + } + } + if (verbosity >= 3) { + fprintf(stderr,"QUERY(err:%d/rows:%d): %s\n",ret,num_rows,query); /* */ + } + + if(num_rows>0) { + return 0; + } else { + return 1; + } + } + + void db_close() + { + mysql_close(dbh); + dbh=NULL; + + if (verbosity >= 2) { + fprintf(stderr,"db_close() called!\n"); + } + } + + void db_ping() + { + if(dbh==NULL || mysql_ping(dbh)) { + if (verbosity >= 2) { + fprintf(stderr,"db_ping() is re-calling open_db!\n"); + } + open_db(db_database,db_host,db_port,db_user,db_password); + } + } + *** db.h.orig Fri Mar 16 13:20:54 2001 --- db.h Thu Feb 22 11:35:17 2001 *************** *** 0 **** --- 1,17 ---- + #ifndef _DB_ + #define _DB_ + + extern char db_database[256]; + extern char db_host[256]; + extern char db_table[256]; + extern char db_user[256]; + extern char db_password[256]; + extern int db_port; + extern int pop_timeout; + + int open_db(char *database, char *host, int port, char *username, char *password); + int check_db(char *remoteip); + void db_ping(); + void db_close(); + + #endif *** Makefile.orig Fri Mar 16 13:16:37 2001 --- Makefile Thu Feb 22 11:28:23 2001 *************** *** 513,518 **** --- 513,522 ---- rules.h stralloc.h ./compile rules.c + db.o: \ + compile db.c db.h + ./compile db.c + scan_ulong.o: \ compile scan_ulong.c scan.h ./compile scan_ulong.c *************** *** 742,757 **** ./compile tcprulescheck.c tcpserver: \ ! load tcpserver.o rules.o remoteinfo.o timeoutconn.o cdb.a dns.a \ time.a unix.a byte.a socket.lib ! ./load tcpserver rules.o remoteinfo.o timeoutconn.o cdb.a \ dns.a time.a unix.a byte.a `cat socket.lib` tcpserver.o: \ compile tcpserver.c uint16.h str.h byte.h fmt.h scan.h ip4.h fd.h \ exit.h env.h prot.h open.h wait.h readwrite.h stralloc.h gen_alloc.h \ alloc.h buffer.h error.h strerr.h sgetopt.h subgetopt.h pathexec.h \ ! socket.h uint16.h ndelay.h remoteinfo.h stralloc.h uint16.h rules.h \ stralloc.h sig.h dns.h stralloc.h iopause.h taia.h tai.h uint64.h \ taia.h ./compile tcpserver.c --- 746,761 ---- ./compile tcprulescheck.c tcpserver: \ ! load tcpserver.o rules.o db.o remoteinfo.o timeoutconn.o cdb.a dns.a \ time.a unix.a byte.a socket.lib ! ./load tcpserver rules.o db.o remoteinfo.o timeoutconn.o cdb.a \ dns.a time.a unix.a byte.a `cat socket.lib` tcpserver.o: \ compile tcpserver.c uint16.h str.h byte.h fmt.h scan.h ip4.h fd.h \ exit.h env.h prot.h open.h wait.h readwrite.h stralloc.h gen_alloc.h \ alloc.h buffer.h error.h strerr.h sgetopt.h subgetopt.h pathexec.h \ ! socket.h uint16.h ndelay.h remoteinfo.h stralloc.h uint16.h rules.h db.h \ stralloc.h sig.h dns.h stralloc.h iopause.h taia.h tai.h uint64.h \ taia.h ./compile tcpserver.c *** conf-ld.orig Fri Mar 16 13:46:36 2001 --- conf-ld Fri Mar 16 13:46:43 2001 *************** *** 1,3 **** ! gcc -s This will be used to link .o files into an executable. --- 1,3 ---- ! gcc -s -I/usr/local/include/mysql -L/usr/local/lib/mysql -lmysqlclient This will be used to link .o files into an executable. *** conf-cc.orig Fri Mar 16 13:47:31 2001 --- conf-cc Fri Mar 16 13:47:37 2001 *************** *** 1,3 **** ! gcc -O2 This will be used to compile .c files. --- 1,3 ---- ! gcc -O2 -I/usr/local/include/mysql This will be used to compile .c files. diff -ruN --exclude conf-* ucspi-tcp-0.88/rblsmtpd.c ucspi-tcp-0.88.fix/rblsmtpd.c --- ucspi-tcp-0.88/rblsmtpd.c Sat Mar 18 10:18:42 2000 +++ ucspi-tcp-0.88.fix/rblsmtpd.c Wed Aug 9 16:42:33 2000 @@ -60,16 +60,54 @@ void rbl(char *base) { + int i; + char *altreply = 0; if (decision) return; if (!stralloc_copy(&tmp,&ip_reverse)) nomem(); + i = str_chr(base, ':'); + if (base[i]) { + base[i] = 0; + altreply = base+i+1; + } if (!stralloc_cats(&tmp,base)) nomem(); - if (dns_txt(&text,&tmp) == -1) { - flagmustnotbounce = 1; - if (flagfailclosed) { - if (!stralloc_copys(&text,"temporary RBL lookup error")) nomem(); - decision = 2; + if (altreply) { + if (dns_ip4(&text,&tmp) == -1) { + flagmustnotbounce = 1; + if (flagfailclosed) { + if (!stralloc_copys(&text,"temporary RBL lookup error")) nomem(); + decision = 2; + } + return; + } + if (text.len) { + if(!stralloc_copys(&text, "")) nomem(); + while(*altreply) { + char *x; + i = str_chr(altreply, '%'); + if(!stralloc_catb(&text, altreply, i)) nomem(); + if(altreply[i] && + altreply[i+1]=='I' && + altreply[i+2]=='P' && + altreply[i+3]=='%') { + if(!stralloc_catb(&text, ip_env, str_len(ip_env))) nomem(); + altreply+=i+4; + } else if(altreply[i]) { + if(!stralloc_cats(&text, "%")) nomem(); + altreply+=i+1; + } else { + altreply+=i; + } + } + } + } else { + if (dns_txt(&text,&tmp) == -1) { + flagmustnotbounce = 1; + if (flagfailclosed) { + if (!stralloc_copys(&text,"temporary RBL lookup error")) nomem(); + decision = 2; + } + return; } - return; } if (text.len) if (flagrblbounce)