diff --git a/src/clamd.c b/src/clamd.c index 64814d7b..542f0b29 100644 --- a/src/clamd.c +++ b/src/clamd.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -77,10 +78,10 @@ int clamd_scan(char *tmpfile, char *engine, char *avinfo, struct __config *cfg){ int clamd_net_scan(char *tmpfile, char *engine, char *avinfo, struct __config *cfg){ - int n, psd; + int n, psd, rc, ret=AV_OK; char *p, *q, buf[MAXBUFSIZE], scan_cmd[SMALLBUFSIZE]; - struct in_addr addr; - struct sockaddr_in clamd_addr; + char port_string[6]; + struct addrinfo hints, *res; memset(avinfo, 0, SMALLBUFSIZE); @@ -88,22 +89,30 @@ int clamd_net_scan(char *tmpfile, char *engine, char *avinfo, struct __config *c if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: trying to pass to clamd", tmpfile); - if((psd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ + snprintf(port_string, sizeof(port_string)-1, "%d", cfg->clamd_port); + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if((rc = getaddrinfo(cfg->clamd_addr, port_string, &hints, &res)) != 0){ + syslog(LOG_PRIORITY, "%s: getaddrinfo for '%s': %s\n", tmpfile, cfg->clamd_addr, gai_strerror(rc)); + return AV_ERROR; + } + + if((psd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1){ syslog(LOG_PRIORITY, "%s: ERR: create socket", tmpfile); - return AV_ERROR; + ret = AV_ERROR; + goto ENDE_CLAMD; } - clamd_addr.sin_family = AF_INET; - clamd_addr.sin_port = htons(cfg->clamd_port); - inet_aton(cfg->clamd_addr, &addr); - clamd_addr.sin_addr.s_addr = addr.s_addr; - bzero(&(clamd_addr.sin_zero), 8); - - if(connect(psd, (struct sockaddr *)&clamd_addr, sizeof(struct sockaddr)) == -1){ + if(connect(psd, res->ai_addr, res->ai_addrlen) == -1){ syslog(LOG_PRIORITY, "%s: CLAMD ERR: connect to %s %d", tmpfile, cfg->clamd_addr, cfg->clamd_port); - return AV_ERROR; + ret = AV_ERROR; + goto ENDE_CLAMD; } + memset(scan_cmd, 0, SMALLBUFSIZE); snprintf(scan_cmd, SMALLBUFSIZE-1, "SCAN %s/%s\r\n", cfg->workdir, tmpfile); @@ -127,9 +136,13 @@ int clamd_net_scan(char *tmpfile, char *engine, char *avinfo, struct __config *c } } - return AV_VIRUS; + ret = AV_VIRUS; } - return AV_OK; + +ENDE_CLAMD: + freeaddrinfo(res); + + return ret; } diff --git a/src/config.h b/src/config.h index cf7a684d..ce27e556 100644 --- a/src/config.h +++ b/src/config.h @@ -13,7 +13,7 @@ #define VERSION "0.1.23-master-branch" -#define BUILD 784 +#define BUILD 785 #define HOSTID "mailarchiver" diff --git a/src/misc.c b/src/misc.c index 14512a42..27652a84 100644 --- a/src/misc.c +++ b/src/misc.c @@ -382,19 +382,6 @@ int recvtimeoutssl(int s, char *buf, int len, int timeout, int use_ssl, SSL *ssl } -/* - * is it a valid dotted IPv4 address - */ - -int isDottedIPv4Address(char *s){ - struct in_addr addr; - - if(inet_aton(s, &addr) == 0) return 0; - - return 1; -} - - void write_pid_file(char *pidfile){ FILE *f; diff --git a/src/piler.c b/src/piler.c index ced50307..5e2db334 100644 --- a/src/piler.c +++ b/src/piler.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -117,10 +118,17 @@ static void child_sighup_handler(int sig){ } +void *get_in_addr(struct sockaddr *sa){ + if(sa->sa_family == AF_INET) return &(((struct sockaddr_in*)sa)->sin_addr); + return &(((struct sockaddr_in6*)sa)->sin6_addr); +} + + static void child_main(struct child *ptr){ int new_sd; - unsigned int clen; - struct sockaddr_in client_addr; + char s[INET6_ADDRSTRLEN]; + struct sockaddr_storage client_addr; + socklen_t addr_size; ptr->messages = 0; @@ -134,15 +142,17 @@ static void child_main(struct child *ptr){ ptr->status = READY; - clen = sizeof(client_addr); - - new_sd = accept(sd, (struct sockaddr *)&client_addr, &clen); + addr_size = sizeof(client_addr); + new_sd = accept(sd, (struct sockaddr *)&client_addr, &addr_size); if(new_sd == -1) continue; ptr->status = BUSY; - syslog(LOG_PRIORITY, "connection from %s", inet_ntoa(client_addr.sin_addr)); + inet_ntop(client_addr.ss_family, get_in_addr((struct sockaddr *)&client_addr), s, sizeof(s)); + + syslog(LOG_PRIORITY, "connection from %s", s); + sig_block(SIGHUP); ptr->messages += handle_smtp_session(new_sd, &data, &cfg); @@ -357,9 +367,10 @@ void initialise_configuration(){ int main(int argc, char **argv){ - int i, yes=1, daemonise=0; - struct sockaddr_in serv_addr; - struct in_addr addr; + int i, rc, yes=1, daemonise=0; + char port_string[6]; + struct addrinfo hints, *res; + while((i = getopt(argc, argv, "c:dvVh")) > 0){ switch(i){ @@ -401,25 +412,34 @@ int main(int argc, char **argv){ if(read_key(&cfg)) fatal(ERR_READING_KEY); - if((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) - fatal(ERR_OPEN_SOCKET); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(cfg.listen_port); - inet_aton(cfg.listen_addr, &addr); - serv_addr.sin_addr.s_addr = addr.s_addr; - bzero(&(serv_addr.sin_zero), 8); + snprintf(port_string, sizeof(port_string)-1, "%d", cfg.listen_port); + + if((rc = getaddrinfo(cfg.listen_addr, port_string, &hints, &res)) != 0){ + fprintf(stderr, "getaddrinfo for '%s': %s\n", cfg.listen_addr, gai_strerror(rc)); + return 1; + } + + + if((sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) + fatal(ERR_OPEN_SOCKET); if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) fatal(ERR_SET_SOCK_OPT); - if(bind(sd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) + if(bind(sd, res->ai_addr, res->ai_addrlen) == -1) fatal(ERR_BIND_TO_PORT); if(listen(sd, cfg.backlog) == -1) fatal(ERR_LISTEN); + freeaddrinfo(res); + + if(drop_privileges(pwd)) fatal(ERR_SETUID);